Sorry guys to wake up this topic again, but I am still not convinced ;-). Only because something accidently work or would make sense from the view of some compilers, doesn't make it legal C++. And only because you don't use the result of a nullptr dereference doesn't make the act of dereferencing less illegal.
1 2 3
|
int* i = 0;
*i;
cout << "boo!";
| |
The code above is actually undefined behaviour, although "*i" is never used.
If you go into the realm of undefined behaviour by dereferencing a null pointer, then you may get results like the one experienced, but this is not something anyone should do by purpose (except if you are standing with the back to a deadline-wall and have a publisher-gun between your eyes ;).
So the point is still: I know that most compilers will static link any call to member functions without actually the need to dereference "this". But is this really covered by the C++ standard?
(And the next question would be: Even if it is covered, is there a good reason to use this feature other than impress people at the next C++ standup party? ;-)
Maybe it boils down to the question whether the both statements are the same or not (which I am not sure):
1 2 3 4 5 6
|
Foo* pFoo = 0;
foo& foo = *pFoo;
foo.doStuff();
Foo* pFoo2 = 0;
pFoo2->doStuff();
| |
Or in other words: Is the default behaviour of operator-> to "dereference this and then call operator.() on the result" or is the default behaviour of operator-> defined somehow special as "call operator.() on the type that you would get if you would dereference the expression -> is applied (without actually dereferencing it)."?
(I know that there is no "operator.", but you get what I mean, right? ;-)
By the way: keep in mind that there is no such thing as an empty struct in C++. "sizeof(Foo)" never returns 0. "new Foo" always allocates at least one byte (never nothing). Two different instances of any struct (including empty ones) always have different addresses. This may or may not have anything to do with the case at hand... ;-)
Ciao, Imi.
PS: guestgulkan: Sorry, make it
Foo()->foo();
. But it probably doesn't apply to our problem here anyway.
PPS: This here is not the "empty base class optimization" - exception mentioned in the standard here. I know that base classes containing no data members do not need to be represented in memory, but here you say that "empty classes do not dereference this to call member functions".