GCC warning on upcasting a float to double

277 views Asked by At

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;
}
1

There are 1 answers

2
John Bollinger On BEST ANSWER

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.