空指针常量可以是任何整数常量表达式,评价为0吗?

问题描述 投票:0回答:2

标准说

"一个值为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. 1 * 0
  2. 0 * 0
  3. 0 - 0
  4. 25 - 25
  5. (-4) + (4)
  6. (0 * ((0 * 25) * 3)
  7. (0) * (-100)

如同其前面的任何一个垂饰一样: (void*)(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按标准,a 空指针.


  • 我的担心是正确的还是有什么问题?

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

就我搜索的情况来看,这个问题在Stack Overflow上应该没有重复。

c pointers null language-lawyer constant-expression
2个回答
7
投票

你说的没错,这些都是有效的。

的第6.6节。C标准 州。

1

constant-expression:
    conditional-expression

...

3 常量表达式不得包含赋值、递增、递减、函数调用或逗号运算符,除非它们被包含在一个未被评估的子表达式中。

...

6整数常数表达式 应具有整数类型,且操作数只能是整数常数、枚举常数、字符常数。sizeof 表达式,其结果是整数常数。_Alignof 表达式以及作为直接操作数的浮动常量。 整数常数表达式中的铸造运算符只能将算术类型转换为整数类型,除非作为操作数的一部分,将整数常数表达式转换为整数类型。sizeof_Alignof 操作符。

你的例子中的每一个表达式都符合这种描述,即:。

  • 所有操作数都是整数常数
  • 表达式是一个 条件表达式 (即不使用赋值或逗号操作符),没有增量、减量或函数调用操作符。
  • 评价为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

2
投票

是的

[C99 6.6/6]: 一个整数常数表达式应具有整数类型,并且只有操作数是整数常数、枚举常数、字符常数、结果是整数常数的 sizeof 表达式以及作为投掷操作数的浮动常数。整数常量表达式中的cast操作符只能将算术类型转换为整数类型,除非作为sizeof操作符的操作数的一部分。

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

[conv.ptr]/1: 一个空指针常量是一个整数字面([lex.icon]),其值为零或一个。价钱 类型 std​::​nullptr_­t. [..]

© www.soinside.com 2019 - 2024. All rights reserved.