在C中&* NULL是否定义明确?

时间:2018-08-05 04:19:59

标签: c language-lawyer

以下哪些版本的C标准(如果有)定义明确?

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

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

这个应该是一个带有明显答案的问题,但是(似乎在此类问题上经常发生)我听到很多人说答案“显然没有定义”为“明显”定义”。

相对而言,以下内容如何? foo是否应该产生c的读数?

extern volatile char c;

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

(同一问题的C ++版本:Is &*NULL well-defined in C++?

1 个答案:

答案 0 :(得分:43)

尽管尝试取消引用空指针会导致未定义的行为,所以*nullPtr是非法的,而&*nullPtr则是定义明确的。 According to footnote 102 in the C11 Draft Standard

  

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

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

  

如果操作数是一元 * 运算符的结果,则不会对该运算符和运算符进行求值,并且结果似乎都被省略了。 ..

C99标准具有相同的语言,但是在C90标准中没有出现,而我对该标准的解读是&*nullPtr的确会在C99之前的实现中引起不确定的行为。

根据C90标准(第6.3.2.3节):

  

一元(地址)运算符的结果是指向由其操作数指定的对象或函数的指针。...

和:

  

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

奇怪的是,尽管我可能找不到它,但在C99 Rationale中没有看到有关此更改的任何讨论。