Ada is defensive by default
The type system of Ada is not merely strongly typed, but sometimes referred to as being super-strongly typed, because it does not allow for any level of implicit conversions. None. Consider the following code in C:
#include <stdio.h> int main(void) { float e; int a; e = 4.7631; a = e; printf("%d\n", a); return 0; }
This is valid code that will compile, run and produce the expected result β the result printed out is 4. C has no issues performing an implicit conversion. Ada on the other hand wonβt even compile similar code. Here is the Ada equivalent:
with ada.Integer_Text_IO; use Ada.Integer_Text_IO; procedure testtyped is a : integer; e : float; begin e := 4.7631; a := e; put(a); end testtyped;
When an attempt is made to compile this, the following error will occur:
testtyped.adb:8:09: expected type "Standard.Integer" testtyped.adb:8:09: found type "Standard.Float"
The problem here is that a
and e
are clearly not the same. Instead, one has to explicitly convert between types, which promotes good design by preventing the mixing of types. In this case, Line 9 in the above code becomes:
a := integer(e);
Also at run-time, errors such as illegal memory accesses, buffer overflows, range violations, off-by-one errors, and array access are tested. These errors can then be handled safely instead of the way languages like C do. For example, consider the following C code:
#include <stdio.h> int main(void) { int x[100]; x[101] = 1; printf("%d\n", x[101]); return 0; }
Again, this is valid code that will compile, run and produce unexpected results. A value is actually stored outside the array x
. Consider the same code written in Ada:
with ada.Integer_Text_IO; use Ada.Integer_Text_IO; procedure testarrOOB is x : array (1..100) of integer; begin x(101) := 1; put(x(101)); end testarrOOB;
Compiling the program will result in the following warnings:
testarroob.adb:6:06: warning: value not in range of subtype of "Standard.Integer" defined at line 4 testarroob.adb:6:06: warning: "Constraint_Error" will be raised at run time testarroob.adb:7:10: warning: value not in range of subtype of "Standard.Integer" defined at line 4 testarroob.adb:7:10: warning: "Constraint_Error" will be raised at run time
It does produce an executable, but running the executable results in an exception being triggered:
raised CONSTRAINT_ERROR : testarroob.adb:6 range check failed
Why is this important? Because in real-time systems, errors such as this have to be avoided. Now ask yourself why it is possible the F-35 code written in C++ does work as intended.