1

Sample code (t0.c):

#include <stdio.h>   // fix for clang, see https://stackoverflow.com/q/69976945/1778275
#if __STDC_IEC_559__ == 1
#pragma message "__STDC_IEC_559__ is 1"
#else
#pragma message "__STDC_IEC_559__ is not 1"
#endif

Invocations:

# gcc 11.2 on Linux on x86-64
$ gcc t0.c -std=c11 -pedantic -Wall -Wextra -fno-rounding-math
t0.c:3:9: note: '#pragma message: __STDC_IEC_559__ is 1'

# clang 13.0.0 on Linux on x86-64
$ clang t0.c -std=c11 -pedantic -Wall -Wextra -ffp-model=fast
t0.c:3:9: warning: __STDC_IEC_559__ is 1 [-W#pragma-messages]

# icc 2021.1.2 on Linux on x86-64
$ icc t0.c -std=c11 -pedantic -Wall -Wextra -fp-model=fast
__STDC_IEC_559__ is 1

Here we see that non-strict floating-point models does not change the value 1 of __STDC_IEC_559__. Why?

UPD20211126: Re:

The switch itself does not change the rounding behaviour, and thus does not change whether the macro is defined.

Now gcc under -fno-rounding-math miscompiles the following program (t1.c):

#include <stdio.h>
#include <float.h>
#include <fenv.h>

#pragma STDC FENV_ACCESS ON

int main(void)
{
#if __STDC_IEC_559__ == 1
    if (fesetround(FE_UPWARD) == 0)
    {
        printf("%a\n", FLT_MIN / 1.0000001f);
    }
#endif
    return 0;       
}

Invocation & execution:

# gcc 11.2 on Linux on x86-64
gcc t1.c -std=c11 -pedantic -Wall -Wextra -lm -fno-rounding-math && ./a.out
t1.c:5: warning: ignoring '#pragma STDC FENV_ACCESS' [-Wunknown-pragmas]
0x1.fffffcp-127

# gcc 11.2 on Linux on x86-64
gcc t1.c -std=c11 -pedantic -Wall -Wextra -lm -frounding-math && ./a.out
t1.c:5: warning: ignoring '#pragma STDC FENV_ACCESS' [-Wunknown-pragmas]
0x1p-126

Here we see that under __STDC_IEC_559__ == 1 the results are different. Unexpected.

Note: Yes, in gcc Pragma STDC * (C99 FP) unimplemented.

UPD20211130. Out of curiosity: if these implementations under non-strict floating-point models do not conform to the specifications in the Annex F, then for which purpose they define __STDC_IEC_559__ to 1?

pmor
  • 5,392
  • 4
  • 17
  • 36
  • Related: [Status of __STDC_IEC_559__ with modern C compilers](https://stackoverflow.com/q/31181897/10871073) – Adrian Mole Nov 25 '21 at 18:33
  • However, I don't think the `-ffp` switches change the representation of floating points - they are still in IEE754 (= ISO/IEC/IEEE 60559) format. – Adrian Mole Nov 25 '21 at 18:35
  • Humans write incorrect software. – Eric Postpischil Nov 26 '21 at 00:12
  • Read the manual. **-frounding-math ... This option should be specified for programs that change the FP rounding mode dynamically**. – n. m. could be an AI Nov 26 '21 at 14:28
  • @n.1.8e9-where's-my-sharem. From [comments](https://stackoverflow.com/q/67137232/1778275): **Each individual combination of switches with a compiler is considered to be a different C implementation**. – pmor Nov 26 '21 at 17:04
  • It is obviously true but frankly I'm not sure what it has to do with anything. – n. m. could be an AI Nov 26 '21 at 17:11
  • @n.1.8e9-where's-my-sharem. In test from UPD20211126 we see two different C implementations, which both define `__STDC_IEC_559__` to `1`, but produce different results. Implementation with `-fno-rounding-math` is expected to not define `__STDC_IEC_559__` to `1`. – pmor Nov 26 '21 at 17:17

2 Answers2

1

-fno-rounding-math is the gcc default. It enables optimisations which assume no-rounding IEEE arithmetic. -frounding-math turns these optimisations off. The switch itself does not change the rounding behaviour, and thus does not change whether the macro is defined.

-frounding-math
  Disable transformations and optimizations that assume default 
  floating-point rounding behavior.  This is round-to-zero for all 
  floating point to integer conversions, and round-to-nearest for all 
  other arithmetic truncations.  This option should be specified for 
  programs that change the FP rounding mode dynamically, or that may 
  be executed with a non-default rounding mode.  This option disables
  constant folding of floating-point expressions at compile time
  (which may be affected by rounding mode) and arithmetic 
  transformations that are unsafe in the presence of sign-dependent 
  rounding modes.

-ffast-math switches the macro off in gcc. It doesn't do so in clang, which is probably a bug.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
-1

Because it seems that they are buggy.

UPD.

  1. Defining __STDC_IEC_559__ to 1 in case of no conformance to the specifications in the Annex F is not a bug.
  2. Usually non-strict floating-point models imply no conformance to the specifications in the Annex F. If so, then it is unclear, for which purpose __STDC_IEC_559__ is defined to 1.
pmor
  • 5,392
  • 4
  • 17
  • 36