6

Sample code (t928.c):

#include <stdio.h>
#include <fenv.h>
#if _MSC_VER && ! __clang__
#pragma fenv_access     (on)
#else
#pragma STDC    FENV_ACCESS ON
#endif

int main(void)
{
        int i = fesetround( FE_UPWARD );
        if ( ! i )
        {
                printf( "%.1f\n", 0.0 );
        }
        return 0;
}

Invocations:

$ clang t928.c -Wall -Wextra -std=c11 -ffp-model=strict -pedantic && ./a.exe
0.1

$ cl t928.c /std:c11 /Za /fp:strict && ./t928.exe
0.1

Versions:

$ clang --version
clang version 12.0.0

$ cl
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29913 for x64

UPD20210824. User chux - Reinstate Monica supposed:

Some compilers have trouble properly including FP support when there is no FP activity in user code. Try adding some.

Here is it:

int main(void)
{
        float f1 = 0.0f;
        float f2 = 0.0f;
        float f3 = 0.0f;
        int i = fesetround(FE_UPWARD);
        if ( ! i )
        {
                printf("%.1f\n", 0.0);
        }
        f3 = f1 + f2;
        printf("%.1f\n", f3);
        return 0;
}

Invocations:

$ gcc t928.c -Wall -Wextra -std=c11 -pedantic && ./a.exe
t928.c:6: warning: ignoring '#pragma STDC FENV_ACCESS' [-Wunknown-pragmas]
    6 | #pragma STDC    FENV_ACCESS     ON
      |
0.0
0.0

$ cl t928.c /std:c11 /Za /fp:strict && ./t928.exe
0.1
0.1

$ clang12 t928.c -Wall -Wextra -std=c11 -ffp-model=strict -pedantic && ./a.exe
0.1
0.1

UPD20210831. Answer from Microsoft:

This is an issue in the Universal CRT with our FE_UPWARD and FE_DOWNWARD rounding modes where some numbers will round up as though they had additional non-zero digits after them. This will be fixed in the Universal CRT and will be included in a future release of the Windows OS and Windows SDK.

pmor
  • 5,392
  • 4
  • 17
  • 36
  • Looks like a compiler/library bug to me. – Jabberwocky Aug 19 '21 at 16:19
  • 2
    C17 7.6.1 (2): *If part of a program tests floating-point status flags, sets floating-point control modes, or runs under non- default mode settings, but was translated with the state for the FENV_ACCESS pragma “off”, the behavior is undefined.* I'm not sure if the code inside `printf` is "part of the program" for these purposes, but if it is then I don't see any guarantee that it was translated with `FENV_ACCESS ON`, so you would have UB. – Nate Eldredge Aug 19 '21 at 18:25
  • 3
    At a practical level, I think you're asking for `printf` to be written so that it behaves properly under any possible state of the floating-point environment - either by extremely defensive programming, or by saving and restoring the environment. I'm not sure if that's a reasonable demand in terms of its efficiency, and it's not clear to me that the standard demands it. – Nate Eldredge Aug 19 '21 at 18:33
  • Some compilers have trouble properly including FP support when there is no FP activity in user code. Try adding some. – chux - Reinstate Monica Aug 22 '21 at 16:22
  • @NateEldredge Under `FENV_ACCESS ON` should compilers use "FENV_ACCESS ON translated" versions all the standard functions? – pmor Aug 24 '21 at 17:14
  • @pmor: Again, I don't think the standard requires that to exist, I don't think it would be very practical for a compiler to provide, and I don't know of any compiler that does so. – Nate Eldredge Aug 24 '21 at 17:16
  • @chux-ReinstateMonica Thanks fore the idea. See UPD20210824. – pmor Aug 24 '21 at 17:22
  • Note also the second bullet point in the coding convention recommendations in C17 7.6/3: "*a function call is assumed to require default floating-point control modes, unless its documentation promises otherwise*". This is not normative, but it supports the position that you should not presume that it is safe to call library functions with non-standard FP modes set (unless they document that it's ok). – John Bollinger Aug 24 '21 at 17:36
  • pmor, Better to add non-deterministic FP (e.g. `scanf("%f"...`), else the optimization may make run-time FP activity moot. – chux - Reinstate Monica Aug 24 '21 at 18:03
  • @pmor If you have an answer, please consider adding it to your own question and select it as the preferred answer. This will help in reading. – Netch Oct 18 '21 at 16:01

1 Answers1

0

Because it is a bug in the Universal CRT.

pmor
  • 5,392
  • 4
  • 17
  • 36