由于
math.h
声明了 int isnan(double x)
和 int isnanf(float x)
,我预计以下代码在使用 gcc -O0 -Wall -Wextra -Wpedantic -Wconversion -Wdouble-promotion
编译时会生成某种“浮动到双重提升”警告。然而,事实并非如此。为什么会这样?
#include <stdio.h>
#include <math.h>
int main()
{
float x = 1.23f;
printf("%s\n", isnan(x) ? "nan" : "number");
return 0;
}
因为
同时声明
math.h
和
int isnan(double x)
int isnanf(float x)
是吗?自 C11 起,C 语言规范仅记录 a type-generic
isnan()
macro 支持所有浮点类型。
我预计以下代码在使用
编译时会生成某种“浮动到双重提升”警告。然而,事实并非如此。为什么会这样?gcc -O0 -Wall -Wextra -Wpedantic -Wconversion -Wdouble-promotion
因为
isnan()
宏支持所有浮点类型。这是一个合理的实现:
#define isnan(x) _Generic((x), \
long double: isnanl, \
default: isnan, \
float: isnanf \
)(x)
(假设仍然提供传统的
isnan()
功能,尽管规范不再需要它。)
泛型选择和定义泛型宏的能力在 C11 中是新的,
isnan()
宏也随之而来。因此,如果您为标准的早期版本选择严格一致性模式,那么我预计不会定义此类宏,并且您会收到预期的警告。