Rob*_*rtS 4 c null integer constants language-lawyer
我有一段代码的两个版本。第一种方法是使用int
变量作为条件测试表达式的一部分,第二种方法是使用整数常量表示相同 - 两者都表示相同的整数值 - 24
。
#include <stdio.h>
int main()
{
int var = 24;
if((!var) == NULL)
{
printf("1");
}
}
Run Code Online (Sandbox Code Playgroud)
#include <stdio.h>
int main()
{
if((!24) == NULL)
{
printf("1");
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译第一个版本时,收到警告:
警告:指针和整数之间的比较
来自 gcc,和
警告:指针和整数之间的比较('int' 和 'void *')[-Wpointer-integer-compare]
从叮当。
当我使用与整数常量相同的值编译几乎等效的代码时,一切都很好。为什么?
到目前为止我的研究:
我查看了 C18 并在第 6.4.4 节“常量”中找到:
首先在小节 /2 和 /3 下:
" 2 - 每个常量都应有一个类型,常量的值应在其类型的可表示值范围内。 "
" 3 - 每个常量都有一个类型,由它的形式和值决定,稍后详述。 "。
第/5 小节下的第二个:
“整数常量的类型是其值可以在其中表示的相应列表中的第一个。 ”
以下列表:
因此,没有后缀且相对于 的可表示值的整数常量24
应该具有类型int
。
我理解警告本身并知道NULL
通常在大多数实现中扩展为(void*) 0
. 因此,抛出此警告是合理的。
但是为什么在使用与整数常量相同的值时不会出现警告?
从 C11 6.3.2.3/3:
值为 0 的整数常量表达式,或转换为 void * 类型的此类表达式,称为空指针常量。
从 6.5.9/2 关于相等运算符==
和!=
:
以下之一应成立:
...
— 一个操作数是一个指针,另一个是空指针常量。
请注意,整数常量表达式不限于整数常量(0、42 等),还可以包括对它们起作用的运算符,例如5+5-10
。
!24
是值为 0 的整数常量表达式,因此计为空指针常量。的==
操作者被允许一个指针和一个空指针恒定,这使得之间作用(!24) == NULL
有效的比较。
在您的第一个示例中,!var
不是整数常量表达式,因为它包含一个变量操作数,因此无法与指针进行比较。
警告:在大多数实现中,NULL
定义为(void*)0
并且以上是正确的。但是,标准允许将其定义为任何空指针常量,例如0
. 如果是这种情况,则比较(!var) == NULL
将编译,因为它与(!var) == 0
.