gpt4 book ai didi

c - 为什么此 C 代码片段中的 NULL 取消引用不会导致未定义的行为

转载 作者:行者123 更新时间:2023-11-30 18:50:42 26 4
gpt4 key购买 nike

我遇到了一段代码,其中 NULL 被类型转换为结构指针类型 (foo *) 0,并且使用该指针取消引用成员 ((foo *)0 )->m,并使用该 &(((foo *)0)->m)) 的地址并将其转换为整数以获取该成员的内存索引在结构体中。((unsigned int)(&(((foo *)0)->m)))

据我所知,NULL 指针取消引用应该总是会导致 C 中的段错误。但我不明白如何像这样取消 NULL 指针的引用而仍然不会导致段错误。

#include <stdio.h>
#define MACRO(m) ((unsigned int)(&(((foo *)0)->m)))

typedef struct
{
int a;
int b;
int c;
int d;
}foo;

int main(void) {
printf("\n %d ", MACRO(c));
return 0;
}

最佳答案

C11 标准在 6.5.3.2 地址和间接运算符中表示:

The unary & operator yields the address of its operand. If the operand has type ''type'', the result has type ''pointer to type''. If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue. Similarly, if the operand is the result of a [] operator, neither the & operator nor the unary * that is implied by the [] is evaluated and the result is as if the & operator were removed and the [] operator were changed to a + operator. Otherwise, the result is a pointer to the object or function designated by its operand.

(强调我的。)脚注说:

Thus, &*E is equivalent to E (even if E is a null pointer)

有趣的是,-> 运算符也不异常(exception)。我不知道这是故意的还是疏忽。因此,在对标准的严格解释中,我会说 &(((foo *)0)->m) 是未定义的行为。但这并不意味着程序必须崩溃或编译器必须提示。

也就是说,在获取 -> 运算符结果的地址时产生相同的异常是完全合理的,这就是大多数编译器所做的。

关于c - 为什么此 C 代码片段中的 NULL 取消引用不会导致未定义的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39409476/

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