Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is calling a nonvirtual member function on a non-constructed "object" well-defined? [duplicate]

Tags:

c++

Inside a constructor, calling non-virtual member functions is permitted.

Does from this fact follow that the following piece of code is well-defined?

struct A {
    void foo { std::cout << "Hi there! My address is: " << this; }
};

A * a = nullptr;
a->foo ();

Answer?

With the help of some links given in the comments, and the links given in the linked pages, I now think that the answer can be found e.g. in

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3035.pdf

§3.8 par. 5, p. 66:

"Before the lifetime of an object has started but after the storage which the object will occupy has been allocated ... [t]he program has undefined behavior if [...] the pointer is used to access a non-static data member or call a non-static member function of the object"

Then it should be even more undefined to call a member function if storage has not been allocated at all.

I guess one important reason why it is a good idea to make it undefined is explained here: https://stackoverflow.com/a/3257755/1419315

like image 895
JohnB Avatar asked Dec 29 '13 20:12

JohnB


1 Answers

That code is undefined behavior.

Note that inside the constructor you can also call virtual member function.

The somewhat tricky part is calling virtual member function during member initialization before the constructor code begins. Still valid but it's not obvious what happens (the point is that until the constructor code begins the object isn't considered yet an instance of its class and virtual member functions get dispatched to the base class).

Some compilers emit a warning if you use this in the member initialization list exactly because the this pointer will behave strangely at that point (it will start behave normally only after the start of the constructor).

The code apparently works because most compilers use the VMT approach for method dispatching but the VMT is not needed to call a non-virtual method and thus if the method code doesn't dereference in any way this then things seems to "work". However the fact that the code seems to work in an implementation (or even in every implementation for that matter) still doesn't make it legal C++ code.

like image 91
6502 Avatar answered Oct 23 '22 13:10

6502