A new feature of C99.
The floating-point environment as defined here includes only execution-time modes, not the 10
myriad of possible translation-time options that can affect a program’s results. Each such option’s deviation from this specification should be well documented.
Dynamic vs. static modes
Dynamic modes are potentially problematic because:
1. the programmer may have to defend against undesirable mode settings, which imposes 15
intellectual as well as time and space overhead.
2. the translator may not know which mode settings will be in effect or which functions change them at execution time, which inhibits optimization.
C99 addresses these problems without changing the dynamic nature of the modes. An alternate approach would have been to present a model of static modes with explicit 20
utterances to the translator about what mode settings would be in effect. This would have avoided any uncertainty due to the global nature of dynamic modes or the dependency on unenforced conventions. However, some essentially dynamic mechanism still would have been needed in order to allow functions to inherit (honor) their caller’s modes. The IEC 60559 standard requires dynamic rounding direction modes. For the many architectures that maintain 25
these modes in control registers, implementation of the static model would be more costly. Also, standard C has no facility, other than pragmas, for supporting static modes.
An implementation on an architecture that provides only static control of modes, for example through opcode encodings, still could support the dynamic model, by generating multiple code streams with tests of a private global variable containing the mode setting. Only modules under 30
an enabling FENV_ACCESS pragma would need such special treatment. Translation
An implementation is not required to provide a facility for altering the modes for translation-time arithmetic, or for making exception flags from the translation available to the executing program.
The language and library provide facilities to cause floating-point operations to be done at execution time when they can be subjected to varying dynamic modes and their exceptions detected. The need does not seem sufficient to require similar facilities for translation.
The fexcept_t type
fexcept_t does not have to be an integer type. Its values must be obtained by a call to 5
fegetexceptflag, and cannot be created by logical operations from the exception macros. An implementation might simply implement fexcept_t as an int and use the representations reflected by the exception macros, but isn’t required to: other representations might contain extra information about the exceptions. fexcept_t might be a struct with a member for each exception (that might hold the address of the first or last floating-point instruction that 10
caused that exception). C99 makes no claims about the internals of an fexcept_t, and so the user cannot inspect it.
Exception and rounding macros
Unsupported macros are not defined in order to assure that their use results in a translation error. A program might explicitly define such macros to allow translation of code (perhaps never 15
executed) containing the macros. An unsupported exception macro should be defined to be 0, for example
#ifndef FE_INEXACT #define FE_INEXACT 0 #endif
20
so that a bitwise OR of macros has a reasonable effect. Exceptions
It was proposed that several of the exception functions return an int indicating whether the excepts argument represents supported exceptions. This facility was deemed unnecessary because excepts&~FE_ALL_EXCEPT can be used to test invalidity of the excepts 25
argument.
Rounding precision
The IEC 60559 floating-point standard prescribes rounding precision modes (in addition to the rounding direction modes covered by the functions in this section) as a means for systems whose results are always double or extended to mimic systems that deliver results to narrower formats. 30
An implementation of C can meet this goal in any of the following ways:
1. By supporting the evaluation method indicated by FLT_EVAL_METHOD equal to 0.
2. By providing pragmas or compile options to shorten results by rounding to IEC 60559 single or double precision.
3. By providing functions to dynamically set and get rounding precision modes which shorten results by rounding to IEC 60559 single or double precision. Recommended are functions fesetprec and fegetprec and macros FE_FLTPREC, FE_DBLPREC, and FE_LDBLPREC, analogous to the functions and macros for the rounding direction modes. This specification does not include a portable interface for precision control because the IEC 5
60559 floating-point standard is ambivalent on whether it intends for precision control to be dynamic (like the rounding direction modes) or static. Indeed, some floating-point architectures provide control modes suitable for a dynamic mechanism, and others rely on instructions to deliver single- and double-format results suitable only for a static mechanism.
7.6.1 The FENV_ACCESS pragma
10
The performance of code under FENV_ACCESSON may well be important; in fact an algorithm may access the floating-point environment specifically for performance. The implementation should optimize as aggressively as the FENV_ACCESS pragma allows. An implementation could also simply honor the floating-point environment in all cases and ignore the pragma. The Committee’s model is that the regions of code that are under FENV_ACCESS OFF do not 15
have to maintain the exception flags, even if there are regions with FENV_ACCESS ON elsewhere in the program.
7.6.2 Floating-point exceptions
7.6.2.3 The feraiseexcept function
Raising overflow or underflow is allowed to also raise inexact because on some architectures the 20
only practical way to raise an exception is to execute an instruction that has the exception as a side effect. Any IEC 60559 operation that raises either overflow or underflow raises inexact as well.
The function is not restricted to accept only valid coincident expressions for atomic operations, so the function can be used to raise exceptions accrued over several operations.
25
7.6.3 Rounding
7.6.3.2 The fesetround function
The fesetround function returns nonzero to indicate success for consistency with other C functions that return a status indicator.
7.6.4 Environment
7.6.4.2 The feholdexcept function
The feholdexcept function returns nonzero to indicate success for consistency with other C functions that return a status indicator.
feholdexcept should be effective on typical IEC 60559 implementations which have the 5
default non-stop mode and at least one other mode for trap handling or aborting. If the implementation provides only the non-stop mode, then installing the non-stop mode is trivial. The Committee considered a feprocentry function, which was equivalent to
fegetenv(envp);
fesetenv(FE_DFL_ENV); 10
feholdexcept is more appropriate for the user model prescribed in §7.6.