Is it legal/well-defined C++ to call a non-static method that doesn't access members through a null pointer?

霸气de小男生 提交于 2019-11-27 14:30:29

This will probably work on most systems, but it is Undefined Behaviour. Quoth the Standard:

5.2.5.3

If E1 has the type “pointer to class X,” then the expression E1->E2 is converted to the equivalent form (*(E1)).E2 [...]

And:

5.2.5.1

A postfix expression followed by a dot . or an arrow ->, optionally followed by the keyword template (14.8.1), and then followed by an id-expression, is a postfix expression. The postfix expression before the dot or arrow is evaluated;58) [...]

58) This evaluation happens even if the result is unnecessary to determine the value of the entire postfix expression, for example if the id-expression denotes a static member.

Evaluation of *x where x is a null pointer results in Undefined Behaviour, so yours is clearly a case of UB, before the function is even entered.

This test is broken even if dereferencing was not an UB. It breaks when this-adjustments for multiple inheritance come into the play:

#include <stdio.h>
class B
{
    int value;
    public:
    void foo()
    {
        if (!this)
            printf("this==0\n");
        else 
            printf("safe\n");
    }
};
class A { public: int anotherValue; };
class Z : public A,public B {};

int main()
{
    Z *z=0;
    z->foo();
}

prints "safe" here.

This is (all together now) undefined behavior. However, for many compilers it will work, with the additional constraint that the method must be non-virtual.

It is UB. A good way to make it crash is to use it as a base class of a derived class that uses multiple inheritance. YMMV.

It doesn't matter if it is legal, it is confusing to the reader. In the implementation where this code works, the vtable is being accessed by type, certainly not by object.

Moreover, I expect that this code was put in to cover for a constructor failure, which would mask a variety of problems elsewhere. Constructor failure should be handled correctly, not with a nasty kludge like the example.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!