我有一段代码的两个版本。第一个版本使用一个 int
变量作为条件测试表达式的一部分,第二个版本则使用一个整数常量 - 两者都表示相同的整数值 - 24
。
#include <stdio.h>
int main()
{
int var = 24;
if((!var) == NULL)
{
printf("1");
}
}
#include <stdio.h>
int main()
{
if((!24) == NULL)
{
printf("1");
}
}
当我尝试编译第一个版本时,我收到了来自gcc的警告:
警告:指针和整数之间的比较
以及来自clang的:
警告:指针和整数之间的比较('int'和'void *')[-Wpointer-integer-compare]
但是当我使用相同的值作为整数常量编译几乎相同的代码时,一切都很好。为什么?
我的研究成果:
我查阅了C18的6.4.4章节“常量”:
首先,在第/2和/3小节下:
“2-每个常量都应有一个类型,并且常量的值应在其类型可表示的范围内。”
“3-每个常量都有一个类型,由其形式和值确定,详见后文。”
其次,在第/5小节下:
“整数常量的类型是其对应列表中第一个可表示其值的类型。”
以下是该列表:
因此,没有后缀并且相对于可表示值24
的整数常量应具有类型int
。
我理解警告本身,并知道在大多数实现中,
NULL
通常扩展为(void*) 0
。因此,抛出此警告是合理的。但是,为什么使用相同的值作为整数常量时不会出现警告?
<stddef.h>
](http://port70.net/~nsz/c/c11/n1570.html#7.19):宏为`NULL`
它扩展为实现定义的空指针常量; 和... - Jonathan Leffler(!24)
视为(0)
,这是一个有效的指针常量(实际上是唯一有效的指针常量)。请参见此处。 - Adrian Mole!24
等于零,零可以与NULL
进行比较(它可以直接转换为void *
)。 - Jonathan Lefflerif((!0) == NULL)
也应该引发警告。 - ad absurdum(!0) == NULL
但不会警告(!1) == NULL
。 - Eric Postpischil