Search code examples
cfloating-pointundefined-behaviorieee-754

How __STDC_IEC_559__ affects UB gaps?


Follow-up for FP: invalid operation: contradiction between C (UB) and IEEE 754 (WDB)?.

When the C standard leaves a gap, other standards and other specifications may fill in that gap.

When the C standard does not define a behavior, the behavior may be defined, partially or completely, by other standards

If __STDC_IEC_559__ is defined, then does it mean that:

  1. All FP related UB gaps are filled with IEEE 754 logic?
  2. FP related UB does not become WDB? (I.e. UB stays UB.)
  3. User shall not rely on IEEE 754 logic's implementation (SW/HW), because "we're already inside the UB"?
  4. Any error in IEEE 754 logic's implementation cannot be viewed as error, because "we're already inside the UB"?

Please, argument your opinion.


Solution

  • When the C language leaves something undefined, what that's doing is giving implementations freedom to define or not to define it in any way they choose. This is why UB serves a purpose not just of allowing dubious optimizations at the expense of safety, but also the opposite choice of defining otherwise-undefined constructs to trap so that they aid in finding bugs (for example, making signed overflow trap). My point here is that undefined behavior is not a mandate on implementations to leave something undefined or to behave in unpredictable/erratic ways, just an allowance.

    Not only particular implementations, but whole specifications built on top of the base C language specification can define the behavior of constructs that the base specification leaves undefined. This happens a lot with POSIX. For example it defines the behavior of fflush on seekable input streams, and the behavior of various operations on text files that would otherwise be undefined (by virtue of defining that text and binary are the same thing).

    "C including Annex F" is such a derivative specification built on top of the base C language specification. As such, when it defines something about floating point behavior that the base language left undefined, that something is no longer undefined.

    Among the options you offered, #1 is the closest to the truth, but it's hard to characterize "all FP related UB gaps" precisely without reducing it to something tautological. For instance aliasing violations involving floating point types, invalid use of variadic functions involving floating point types, etc. are "FP related" but of course still undefined. The gaps that are filled are precisely those that are filled by Annex F.