gpt4 book ai didi

c - &((struct name *)NULL -> b) 会导致 C11 中的未定义行为吗?

转载 作者:太空宇宙 更新时间:2023-11-04 12:53:52 25 4
gpt4 key购买 nike

代码示例:

struct name
{
int a, b;
};

int main()
{
&(((struct name *)NULL)->b);
}

这会导致未定义的行为吗?我们可以争论它是否“取消引用 null”,但是 C11 没有定义术语“取消引用”。

6.5.3.2/4 明确指出在空指针上使用 * 会导致未定义的行为;但是它对 -> 的说法不一样,也没有将 a -> b 定义为 (*a).b ;它对每个运算符都有单独的定义。

6.5.2.3/4 中 -> 的语义说:

A postfix expression followed by the -> operator and an identifier designates a member of a structure or union object. The value is that of the named member of the object to which the first expression points, and is an lvalue.

但是,NULL 没有指向对象,因此第二句似乎未指定。

同样相关的可能是 6.5.3.2/1:

Constraints:

The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.

但是我觉得粗体文本有缺陷,应该阅读 lvalue that potentially designates an object ,按照 6.3.2.1/1(lvalue 的定义)—— C99 搞乱了左值的定义,所以 C11 不得不重写它,也许这部分被遗漏了。

6.3.2.1/1 确实说:

An lvalue is an expression (with an object type other than void) that potentially designates an object; if an lvalue does not designate an object when it is evaluated, the behavior is undefined

然而,& 运算符确实 计算其操作数。 (它不访问存储的值,但这是不同的)。

这一长串推理似乎表明该代码会导致 UB,但它相当脆弱,我不清楚标准编写者的意图。如果他们实际上有任何意图,而不是留给我们辩论:)

最佳答案

从律师的角度来看,表达式 &(((struct name *)NULL)->b); 应该导致 UB,因为你找不到一条路径没有UB。恕我直言,根本原因是您在不指向对象的表达式上应用 -> 运算符。

从编译器的角度来看,假设编译器程序员没有过于复杂,很明显表达式返回与 offsetof(name, b) 相同的值,我很确定如果编译没有错误任何现有的编译器都会给出该结果。

正如所写,我们不能责怪编译器会注意到在内部部分你使用运算符 -> 一个表达式而不是指向一个对象(因为它是空的)并发出一个警告或错误。

我的结论是,除非有一个特殊的段落说只要它只是取它的地址,它是合法的解引用一个空指针,这个表达式是不合法的 C。

关于c - &((struct name *)NULL -> b) 会导致 C11 中的未定义行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47637755/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com