繁体   English   中英

是否对 C++ 中定义的 null 指针进行成员访问?

[英]Is member access on a null pointer defined in C++?

null 指针上的地址计算是否在 C++ 中定义了行为? 这是一个简单的示例程序。

struct A { int x; };
int main() {
  A* p = nullptr;
  &(p->x);  // is this undefined behavior?
  return 0;
}

谢谢。

编辑下标包含在另一个问题中。

 &(p->x); // is this undefined behavior?

标准对此有点模糊:

[expr.ref]... 表达式 E1->E2 被转换为等价形式 (*(E1)).E2;

[expr.unary.op] 一元 * 运算符...结果是一个左值,引用表达式指向的 object...。

该部分没有明确提及UB。 引用的规则似乎与 null 指针不指向任何 object 的事实相冲突。 这可以解释为是的,行为未定义。

[expr.unary.op] 一元 & 运算符的结果是指向其操作数的指针。 ...如果操作数是 T 类型的左值,则结果表达式是“指向 T”的指针类型的纯右值,其结果是指向指定 object ([intro.memory]) 的指针。

同样,不存在指定的 object。 请注意,操作数左值在任何时候都不会转换为右值,而右值肯定是 UB。

早在 2000 年,就有一个CWG 问题来澄清通过 null 的间接是否未定义。 提议的决议 (2004) 将阐明通过 null 的间接不是UB,目前似乎尚未添加到标准中。

但是,它是否是 UB 并不重要,因为您不需要这样做。 至少,结果指针将是无效的,因此无用。

如果您打算将指针转换为 integer 以获取成员的偏移量,则无需这样做,因为您可以使用标准库中的offsetof宏来代替,它没有 UB。


 &(p[1]); // undefined?

在这里,行为显然是未定义的:

[expr.sub]... 表达式 E1[E2] 与 *((E1)+(E2)) 相同(根据定义),除了在数组操作数的情况下,如果该操作数的结果是左值是左值,否则是 xvalue。

[expr.add] 当一个整数类型的表达式 J 被添加到一个指针类型的表达式 P 中或从一个表达式 P 中减去时,结果具有 P 的类型。

  • 如果 P 计算结果为 null 指针值且 J 计算结果为 0(不适用)

  • 否则,如果 P 指向一个数组元素(不适用)

  • 否则,行为未定义。


 &(p[0]); // undefined?

根据之前的规则,第一个选项适用:

如果 P 计算结果为 null 指针值且 J 计算结果为 0,则结果为 null 指针值。

现在我们回到通过这个 null 间接是否是 UB 的问题。 请参阅答案的开头。

不过,其实也无所谓。 没有必要写这个,因为这只是写sizeof(int) * ii分别为 1 和 0)的不必要的复杂方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM