是否使用null这个未定义的行为调用非虚方法?

时间:2014-03-16 01:33:01

标签: c++ language-lawyer undefined-behavior

简而言之,这是未定义的行为吗?

struct C { int Fn() { return 42; }};

int main() {
  C *c = nullptr;
  return c->Fn();
}

一个重要的细节是C::Fn永远不会对this指针做任何事情(显式或隐式)。我从经验上知道,有些编译器生成的代码完全符合我的要求,但是如果这会让UB感到烦恼,那么我无法依靠它保持真实。

我发现的唯一相关问题是this one that would be relevant,但我的情况是不使用参考文献。


编辑:这与以下情况高度相关:

void Foo(int len) {
  if (len > 1) {
    // This can legally be assumed to be dead code;
  }

  C c;
  C* a[2] = {&c, nullptr};

  for (int i = 0; i < len ; i++) a[i]->Fn();
} 

1 个答案:

答案 0 :(得分:0)

使用N3797,S9.3.1:

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.

没有关于&#39;指向类型&#39;的指针。我在这里读到,通过解引用指针找到的对象必须是X类型,而null不是。解除引用可在5.2.5中找到:

For the first option (dot) the first expression shall have complete class type. For the second option (arrow) the first expression shall have pointer to complete class type. The expression E1->E2 is converted to the equivalent form (*(E1)).E2; the remainder of 5.2.5 will address only the first option (dot).67

如果您触摸指针,则会遇到S5.1.1 / 1:

The keyword this names a pointer to the object for which a non-static member function (9.3.2) is invoked or a non-static data member’s initializer (9.2) is evaluated.

对于任何除了指向对象的有效指针之外的任何调用,我的投票都是UB。 Null是UB。