Next: , Previous: Use of Boolean Constants, Up: Conditional Compilation


D.2 Debugging - A Special Case

A common use of conditional code is to execute statements (for example dynamic checks, or output of intermediate results) under control of a debug switch, so that the debugging behavior can be turned on and off. This can be done using a Boolean constant to control whether the code is active:

     if Debugging then
        Put_Line ("got to the first stage!");
     end if;

or

     if Debugging and then Temperature > 999.0 then
        raise Temperature_Crazy;
     end if;

Since this is a common case, there are special features to deal with this in a convenient manner. For the case of tests, Ada 2005 has added a pragma Assert that can be used for such tests. This pragma is modeled on the Assert pragma that has always been available in GNAT, so this feature may be used with GNAT even if you are not using Ada 2005 features. The use of pragma Assert is described in Pragma Assert, but as an example, the last test could be written:

     pragma Assert (Temperature <= 999.0, "Temperature Crazy");

or simply

     pragma Assert (Temperature <= 999.0);

In both cases, if assertions are active and the temperature is excessive, the exception Assert_Failure will be raised, with the given string in the first case or a string indicating the location of the pragma in the second case used as the exception message.

You can turn assertions on and off by using the Assertion_Policy pragma. This is an Ada 2005 pragma which is implemented in all modes by GNAT, but only in the latest versions of GNAT which include Ada 2005 capability. Alternatively, you can use the -gnata switch to enable assertions from the command line (this is recognized by all versions of GNAT).

For the example above with the Put_Line, the GNAT-specific pragma Debug can be used:

     pragma Debug (Put_Line ("got to the first stage!"));

If debug pragmas are enabled, the argument, which must be of the form of a procedure call, is executed (in this case, Put_Line will be called). Only one call can be present, but of course a special debugging procedure containing any code you like can be included in the program and then called in a pragma Debug argument as needed.

One advantage of pragma Debug over the if Debugging then construct is that pragma Debug can appear in declarative contexts, such as at the very beginning of a procedure, before local declarations have been elaborated.

Debug pragmas are enabled using either the -gnata switch that also controls assertions, or with a separate Debug_Policy pragma. The latter pragma is new in the Ada 2005 versions of GNAT (but it can be used in Ada 95 and Ada 83 programs as well), and is analogous to pragma Assertion_Policy to control assertions.

Assertion_Policy and Debug_Policy are configuration pragmas, and thus they can appear in gnat.adc if you are not using a project file, or in the file designated to contain configuration pragmas in a project file. They then apply to all subsequent compilations. In practice the use of the -gnata switch is often the most convenient method of controlling the status of these pragmas.

Note that a pragma is not a statement, so in contexts where a statement sequence is required, you can't just write a pragma on its own. You have to add a null statement.

     if ... then
        ... -- some statements
     else
        pragma Assert (Num_Cases < 10);
        null;
     end if;