C中的&* NULL定义良好吗?

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

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

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

应该是一个有明显答案的问题,但是(在这些问题上似乎经常发生的事情)我听到的同样多的人说答案“显然是未定义的”,因为“明确定义”。

在一个相当相关的说明,以下是什么? 应该foo产生c的读数?

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

(相同问题的C ++版本: 在C ++中是否定义了&* NULL? )

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

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

这是因为对于一元&算子这一事实( §6.5.3.2¶3 ):

如果操作数是一元*运算符的结果,那么运算符和运算符都不会被计算,结果就好像两个都被省略了,….

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

根据C90标准(§6.3.2.3):

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

和:

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

奇怪的是,我没有看到在C99基本原理中对这种变化的任何讨论,尽管我可能只是找不到它。