In Ada, the predefined floating-point types (Short_Float, Float, Long_Float, Long_Long_Float) are defined to be `unconstrained'. This means that even though each has a well-defined base range, an operation that delivers a result outside this base range is not required to raise an exception. This implementation permission accommodates the notion of infinities in IEEE floating-point, and corresponds to the efficient execution mode on most machines. GNAT will not raise overflow exceptions on these machines; instead it will generate infinities and NaN’s as defined in the IEEE standard.
Generating infinities, although efficient, is not always desirable. Often the preferable approach is to check for overflow, even at the (perhaps considerable) expense of run-time performance. This can be accomplished by defining your own constrained floating-point subtypes – i.e., by supplying explicit range constraints – and indeed such a subtype can have the same base range as its base type. For example:
subtype My_Float is Float range Float'Range;
Here My_Float has the same range as Float but is constrained, so operations on My_Float values will be checked for overflow against this range.
This style will achieve the desired goal, but it is often more convenient to be able to simply use the standard predefined floating-point types as long as overflow checking could be guaranteed. The Check_Float_Overflow configuration pragma achieves this effect. If a unit is compiled subject to this configuration pragma, then all operations on predefined floating-point types including operations on base types of these floating-point types will be treated as though those types were constrained, and overflow checks will be generated. The Constraint_Error exception is raised if the result is out of range.
This mode can also be set by use of the compiler switch `-gnateF'.