我正在阅读关于C++中nullptr的一些特殊性质的帖子,其中一个例子让我有些困惑。
考虑以下内容(来自上述帖子的简化示例):
根据作者的说法,解引用空指针的表达式
然而,如何保证
那么,为什么在处理UB的因果关系时要对
考虑以下内容(来自上述帖子的简化示例):
struct A {
void non_static_mem_fn() {}
static void static_mem_fn() {}
};
A* p{nullptr};
/*1*/ *p;
/*6*/ p->non_static_mem_fn();
/*7*/ p->static_mem_fn();
根据作者的说法,解引用空指针的表达式
/*1*/
本身不会导致未定义行为。同样,使用空指针对象调用静态函数的表达式/*7*/
也是如此。其理由基于C++标准核心语言已关闭问题中的issue 315,其中有以下描述:"当p
为空时,除非该左值被转换为右值(7.1 [conv.lval]),否则*p
不是错误",从而区分了/*6*/
和/*7*/
。因此,实际上对空指针进行解引用不属于未定义行为(在SO上的回答, 在C++标准的232号问题下的讨论等)。因此,在这种假设下,/*1*/
的有效性是可以理解的。然而,如何保证
/*7*/
不会导致未定义行为呢?根据引用的语句,在p->static_mem_fn();
中没有将左值转换为右值。但是对于/*6*/
的p->non_static_mem_fn();
也是如此。我认为,在相同的问题315中,以下描述证实了我的猜测:"即使non_static_mem_fn();
为空,/*6*/
在12.2.2 [class.mfct.non-static]中明确说明是未定义的"(在引用中,我更改了"which"和f()
以获取与本问题中使用的符号的联系)。
那么,为什么在处理UB的因果关系时要对
p->static_mem_fn();
p->non_static_mem_fn();
nullptr
的指针调用静态函数的使用场景?
附录:
- 这个问题询问为什么解引用
nullptr
是未定义的行为。虽然我同意在大多数情况下这是一个坏主意,但我不认为这个声明在这里的链接和引用中是绝对正确的。 - 类似的讨论在这个问答中,其中包含一些与232号问题有关的链接。
- 我没有找到一个专门探讨静态方法和
nullptr
解引用问题的问题。也许我错过了一些明显的答案。