空指针常量可以是任何计算为 0 的整数常量表达式吗?

Can a null pointer constant be any integer constant expression evaluated to 0?

标准说:

"An integer constant expression with the value 0, or such an expression cast to type void*, is called a null pointer constant.67) If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function."


"67) The macro NULL is defined in stddef.h (and other headers) as a null pointer constant; see 7.19."

Source: ISO/IEC 9899:2018 (C18), §6.2.3.2/3 "Pointers".

最常见的空指针常量当然是0(void*) 0,被大多数实现用作空指针常量,但作为标准要求 - "值为 0 的整型常量表达式,或此类表达式转换为类型 void*" - 空指针常量 也应是以下任何一项:

  1. 1 * 0
  2. 0 * 0
  3. 0 - 0
  4. 25 - 25
  5. (-4) + (4)
  6. (0 * ((0 * 25) * 3)
  7. (0) * (-100)

就像他们的任何吊坠一样,前面有 (void*)、f.e。 (void*) (1 * 0)(void*) (25 - 25).

以及布尔表达式:

  1. (void*) ((1 + 1) == 25)
  2. (void*) !(9)

因此,任何类似以下之一的陈述:

  1. int* ptr = 25 - 25;
  2. int* ptr = (void*) ((-4) + 4);
  3. int* ptr = (0 * ((0 * 25) * 3);
  4. int* ptr = (void*) !(9);
  5. int* ptr = ((1 + 1) == 25);

ptr,按照标准,一个空指针


我正在寻找 C 标准中任何使这篇论文无效的部分。

据我搜索,Stack Overflow 上应该没有重复的这个问题。

是的。

[C99 6.6/6]: An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof operator.

请注意,在 C++ 中情况并非如此,空指针常量的定义不同:

[conv.ptr]/1: A null pointer constant is an integer literal ([lex.icon]) with value zero or a prvalue of type std​::​nullptr_­t. [..]

你是对的,所有这些都是有效的。

C standard 的第 6.6 节指出:

1

constant-expression:
    conditional-expression

...

3 Constant expressions shall not contain assignment, increment, decrement, function-call,or comma operators, except when they are contained within a subexpression that is not evaluated.

...

6 An integer constant expression shall have integer type and shall only have operands that are integer constants,
enumeration constants, character constants, sizeof expressions whose results are integer constants, _Alignof expressions, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof or _Alignof operator.

您示例中的每个表达式都符合此描述,即:

  • 所有操作数都是整型常量
  • 表达式是 条件表达式(即不使用赋值或逗号运算符),没有递增、递减或函数调用运算符
  • 计算为 0

因此,将 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