Next: Style Checking, Previous: Debugging and Assertion Control, Up: Switches for gcc
The Ada Reference Manual defines the concept of invalid values (see RM 13.9.1). The primary source of invalid values is uninitialized variables. A scalar variable that is left uninitialized may contain an invalid value; the concept of invalid does not apply to access or composite types.
It is an error to read an invalid value, but the RM does not require run-time checks to detect such errors, except for some minimal checking to prevent erroneous execution (i.e. unpredictable behavior). This corresponds to the -gnatVd switch below, which is the default. For example, by default, if the expression of a case statement is invalid, it will raise Constraint_Error rather than causing a wild jump, and if an array index on the left-hand side of an assignment is invalid, it will raise Constraint_Error rather than overwriting an arbitrary memory location.
The -gnatVa may be used to enable additional validity checks, which are not required by the RM. These checks are often very expensive (which is why the RM does not require them). These checks are useful in tracking down uninitialized variables, but they are not usually recommended for production builds.
The other -gnatVx switches below allow finer-grained control; you can enable whichever validity checks you desire. However, for most debugging purposes, -gnatVa is sufficient, and the default -gnatVd (i.e. standard Ada behavior) is usually sufficient for non-debugging use.
The -gnatB switch tells the compiler to assume that all values are valid (that is, within their declared subtype range) except in the context of a use of the Valid attribute. This means the compiler can generate more efficient code, since the range of values is better known at compile time. However, an uninitialized variable can cause wild jumps and memory corruption in this mode.
The -gnatVx switch allows control over the validity
checking mode as described below.
The x
argument is a string of letters that
indicate validity checks that are performed or not performed in addition
to the default checks required by Ada as described above.
in
should be validity checked.
in
mode parameters
Arguments for parameters of mode in
are validity checked in function
and procedure calls at the point of call.
in out
mode parameters.
Arguments for parameters of mode in out
are validity checked in
procedure calls at the point of call. The 'm'
here stands for
modify, since this concerns parameters that can be modified by the call.
Note that there is no specific option to test out
parameters,
but any reference within the subprogram will be tested in the usual
manner, and if an invalid value is copied back, any reference to it
will be subject to validity checking.
Standard
,
the shift operators defined as intrinsic in package Interfaces
and operands for attributes such as Pos
. Checks are also made
on individual component values for composite comparisons, and on the
expressions in type conversions and qualified expressions. Checks are
also made on explicit ranges using `..' (e.g. slices, loops etc).
return
statements in functions is validity
checked.
if
, while
or exit
statements are checked, as well as guard expressions in entry calls.
The -gnatV switch may be followed by
a string of letters
to turn on a series of validity checking options.
For example,
-gnatVcr
specifies that in addition to the default validity checking, copies and
function return expressions are to be validity checked.
In order to make it easier
to specify the desired combination of effects,
the upper case letters CDFIMORST
may
be used to turn off the corresponding lower case option.
Thus
-gnatVaM
turns on all validity checking options except for
checking of in out procedure arguments.
The specification of additional validity checking generates extra code (and
in the case of -gnatVa the code expansion can be substantial).
However, these additional checks can be very useful in detecting
uninitialized variables, incorrect use of unchecked conversion, and other
errors leading to invalid values. The use of pragma Initialize_Scalars
is useful in conjunction with the extra validity checking, since this
ensures that wherever possible uninitialized variables have invalid values.
See also the pragma Validity_Checks
which allows modification of
the validity checking mode at the program source level, and also allows for
temporary disabling of validity checks.