首页 > 解决方案 > &*NULL 在 C 中是否定义明确?

问题描述

以下是在 C 标准的哪个版本(如果有)中明确定义的?

void foo(void) {
    char *nullPtr = NULL;
    &*nullPtr;
}

请注意,我没有将结果分配给任何东西——第二行是一个简单的语句。

应该是一个有明显答案的问题,但是(就像在此类问题上似乎经常发生的那样)我听到很多人说答案是“明显未定义”和“明显定义”。

在一个相当相关的说明中,以下内容呢?应该foo产生一个读c吗?

extern volatile char c;

void bar(void) {
    volatile char *nonnullptr = &c;
    &*nonnullptr;
}

(同一问题的 C++ 版本:&*NULL 在 C++ 中是否明确定义?

标签: clanguage-lawyer

解决方案


虽然尝试取消引用空指针会导致未定义的行为,但这*nullPtr是非法的,但&*nullPtr完全定义良好。根据 C11 标准草案中的脚注 102

因此,&*E等价于E(即使E是空指针),....

这是因为对于一元运算&符(§6.5.3.2 ¶3):

如果操作数是一元*运算符的结果,则该运算符和&运算符都不会被计算,结果就好像两者都被省略了一样,......

C99 标准具有相同的语言,但这并没有出现在 C90 标准中,我对该标准的解读是,&*nullPtr这确实会导致 C99 之前的实现中出现未定义的行为。

来自 C90 标准(§6.3.2.3):

一元& (address-of) 运算符的结果是指向由其操作数指定的对象或函数的指针....

和:

一元 * 运算符表示间接......如果已为指针分配了无效值,则一元 * 运算符的行为未定义。

奇怪的是,我在C99 Rationale中没有看到任何关于这种变化的讨论,尽管我可能只是没有找到它。


推荐阅读