标准说
"一个值为0的整数常数表达式,或者这样的表达式被转为类型为
void*
,被称为 空指针常数.67)如果将一个空指针常量转换为指针类型,则产生的指针,称为 空指针,保证与任何对象或函数的指针比较不等。""67)宏NULL在stddef.h(和其他头文件)中被定义为空指针常数;见7.19。"
资料来源:ISOIEC 9899:2018(C18),§6.2.3.23 "指针"。ISOIEC 9899:2018(C18),§6.2.3.23 "指针"。
最常见的 空指针常量 当然是。0
和 (void*) 0
被大多数实现所采用,作为 空指针常数但正如标准规定的那样-- "值为0的整数常数表达式。,或者这样的表达式转为类型 void*
" - a 空指针常数 也应是以下任何一种。
1 * 0
0 * 0
0 - 0
25 - 25
(-4) + (4)
(0 * ((0 * 25) * 3)
(0) * (-100)
如同其前面的任何一个垂饰一样: (void*)
即 (void*) (1 * 0)
或 (void*) (25 - 25)
.
以及布尔表达式。
(void*) ((1 + 1) == 25)
(void*) !(9)
因此,任何类似这样的语句:
int* ptr = 25 - 25;
int* ptr = (void*) ((-4) + 4);
int* ptr = (0 * ((0 * 25) * 3);
int* ptr = (void*) !(9);
int* ptr = ((1 + 1) == 25);
将使 ptr
按标准,a 空指针.
我正在寻找C标准的任何部分使这个论文无效。
就我搜索的情况来看,这个问题在Stack Overflow上应该没有重复。
你说的没错,这些都是有效的。
的第6.6节。C标准 州。
1
constant-expression: conditional-expression
...
3 常量表达式不得包含赋值、递增、递减、函数调用或逗号运算符,除非它们被包含在一个未被评估的子表达式中。
...
6 安 整数常数表达式 应具有整数类型,且操作数只能是整数常数、枚举常数、字符常数。
sizeof
表达式,其结果是整数常数。_Alignof
表达式以及作为直接操作数的浮动常量。 整数常数表达式中的铸造运算符只能将算术类型转换为整数类型,除非作为操作数的一部分,将整数常数表达式转换为整数类型。sizeof
或_Alignof
操作符。
你的例子中的每一个表达式都符合这种描述,即:。
所以,所有这些都是有效的分配方式。NULL
到一个指针。
一些例子是 不 整数常数表达式。
int x = 1;
int *ptr1 = (3, 0); // invalid, comma operator not allowed
int *ptr2 = (x = 0); // invalid, assignment not allowed
int *ptr3 = x - 1; // invalid, an operand is not an integer constant
是的
[C99 6.6/6]:
一个整数常数表达式应具有整数类型,并且只有操作数是整数常数、枚举常数、字符常数、结果是整数常数的 sizeof 表达式以及作为投掷操作数的浮动常数。整数常量表达式中的cast操作符只能将算术类型转换为整数类型,除非作为sizeof操作符的操作数的一部分。
注意,在C++中并非如此,在C++中,空指针常量的定义不同。
[conv.ptr]/1:
一个空指针常量是一个整数字面([lex.icon]),其值为零或一个。价钱 类型std::nullptr_t
. [..]