cgccgcc-warningtype-promotion

GCC warning on upcasting a float to double


Since math.h declares both int isnan(double x) and int isnanf(float x), I expected the following code, when compiled with gcc -O0 -Wall -Wextra -Wpedantic -Wconversion -Wdouble-promotion to generate some kind of "float to double promotion" warning. However, it does not. Why is this the case?

#include <stdio.h>
#include <math.h>

int main()
{
  float x = 1.23f;
  printf("%s\n", isnan(x) ? "nan" : "number");
  return 0;
}

Solution

  • Since math.h declares both int isnan(double x) and int isnanf(float x)

    Does it? The C language specification documents only an isnan() macro supporting all floating-point types. If the implementation provides an isnan() function accepting an argument of type double then I expect that to be shadowed by the macro in a conforming implementation.

    I expected the following code, when compiled with gcc -O0 -Wall -Wextra -Wpedantic -Wconversion -Wdouble-promotion to generate some kind of "float to double promotion" warning. However, it does not. Why is this the case?

    Because the isnan() macro supports all floating-point types, and your particular one does it without a conversion that would elicit such a warning. Here's a plausible implementation as a type-generic macro:

    #define isnan(x) _Generic((x), \
        long double: isnanl,       \
        default: isnan,            \
        float: isnanf              \
    )(x)
    

    (That assumes that the designated functions are available, including isnan(double), though C does not require that.)

    Generic selection and the ability to define type-generic macros was new in C11. Therefore, if you select a strict-conformance mode for an earlier version of the standard then it would not be surprising to get a version that actually does perform some kind of conversion.