以下哪些版本的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++?)
答案 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中没有看到有关此更改的任何讨论。