在 nullptr 上调用无状态 class 的非静态成员函数是否合法?

Is it legal to call a non-static member function of a stateless class on a nullptr?

考虑以下代码:

int main()
{
    struct EmptyStruct{
        void nonstatic_mf() const { std::cout <<"EmptyStruct\n"; }
    };


    EmptyStruct *esptr = nullptr;
    esptr->nonstatic_mf(); 
}  

这是合法的 C++ 吗(它似乎在 gcc 和 clang 中工作)?

即使该结构为空,它的大小也非零。肯定有一些内存作为它的存储。

没有。这始终是 UB。如果您不需要该实例,请将其设为静态。仍然可以使用点 . 语法调用静态函数。

为什么?因为您不能取消引用空指针。调用等效于此的成员函数:

 EmptyStruct *esptr = nullptr;
 (*esptr).nonstatic_mf();

可以看到,空指针是deferenced的,也就是UB

标准对此有何规定?来自 [class.mfct.non-static]/2:

If a non-static member function of a class X is called for an object that is not of type X, or of a type derived from X, the behavior is undefined.

空指针不指向 EmptyStruct 的有效实例。仅此一项就足以使行为未定义

来自 [expr.ref]/2

For the first option (dot) the first expression shall be a glvalue. For the second option (arrow) the first expression shall be a prvalue having pointer type. The expression E1->E2 is converted to the equivalent form (*(E1)).E2; the remainder of [expr.ref] will address only the first option (dot).

所以 esptr->nonstatic_mf() 实际上等同于 (*esptr).nonstatic_mf(),取消引用空指针是未定义的行为。

所以这段代码有两种未定义的方式。