Calling a C++ member function with a null object
In today's post, I'll show you what happens if you call a member function on a null object.
C++ is interesting, and sometimes it surprises me. Then, I forget and get surprised again...
What happened? In a code-review I approached the following code (compiler-explorer.com/z/8abxaKq3d):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
To the programmer's surprise, this code did compile and even run! Oh, yes, it did. Even without crashing! Well, at least as long as nobody invokes Set
on alfred
.
The way member functions in C++ work is that each non-static member function has an implicit first parameter, the this
pointer. Rings a bell, right?
The call to Fun
internally looks like this:
1 |
|
while Fun
and Set
s signature is:
1 2 3 |
|
You can call a member function on a null-object because in the case of Fun
, the this
-pointer, which in our example is a nullptr
, isn't used! Once you invoke Set
the this
-pointer is used for accessing the data member mValue
inside Set
.
As a side note, checking for the this
-pointer being a nullptr
is undefined behavior as everything from above is. Lifetime [basic.life p6.2] lists calling a member function with a nullptr
among other things. Since [basic.life p6.2] clearly states that calling a member function with a nullptr
is UB, the compiler can assume a non-null pointer inside any member function and hence is allowed to optimize away any nullptr
check because it can only be constant false
.
Of course, I knew all that, but seeing the example caught me by surprise, and I struggled for a moment :-)
Andreas