#include "iostream"
using namespace std;
class A
{
public:
void mprint()
{
cout<<"\n TESTING NULL POINTER";
}
};
int main()
{
A *a = NULL;
a->mprint();
return 0;
}
I am getting output as "TESTING NULL POINTER". Can anyone please explain why this program is printing the output instead of crashing. I checked it on Dev C++ and aCC compiler both gave same result.
According to the C++ spec, This program has undefined behavior because you're invoking a member function on a null receiver.
The reason that this works, though, is that non virtual member functions are typically implemented as regular functions that take the "this" pointer as an implicit first argument. Consequently, if you call a member function on a null pointer, as long as you don't use the this pointer, your program will not crash. Of course, you cannot rely n this; a valid C++ compiler could cause this to crash.
However, virtual functions are a different story because the function that actually gets called needs to be resolved at runtime. This usually involves introspecting on the receiver's virtual function table. Thus if you try calling a virtual member function on a null pointer, even if te function doesn't access this, it will still cause a crash. Try this out if you're curious!
Simple Answer: Because
mprint()
is not using any of the member variables of the classDetailed Answer: When a method of a class is called, class instance is passed on to the callee function (normally as the first argument, however, in some calling conventions such as __thiscall, this is passed in a register). This class instance is used to access all the member variables that are used in the callee method.
In this case, this instance is NULL but this doesnt make any difference since no member variables are being used in the callee method. Try changing your code such that you print the value of a member variable in
mprint()
method and you will get the crash.You're not using any member variables of
A
- the function is completely independent of theA
instance, and therefore the generated code happens to not contain anything that dereferences 0. This is still undefined behavior - it just may happen to work on some compilers. Undefined behavior means "anything can happen" - including that the program happens to work as the programmer expected.If you e.g. make
mprint
virtual you may get a crash - or you may not get one if the compiler sees that it doesn't really need a vtable.If you add a member variable to A and print this, you will get a crash.
The results of calling a member function using a null pointer to an object is undefined behavour in c++ so it can do anything.
In this case it's likely because it's rewritten your function as it it was like this
and your call like this
So it's just called it as if it was an ordinary function and passed the null pointer as a parameter which you never then actually use in any way. That explains why it doesn't crash, but the compiler is free to do pretty much anything
Being able of invoking non-virtual member functions on non-valid pointers even enables encoding the information associated to an object in the pointer itself. For example:
This can also be used to implement tagged pointers, that is, pointers that contain meta-information about the pointee.
These two idioms are used in Google Chrome's javascript VM V8 to represent 31-bit integers
This is completely legal call.
lets understand how it works
when a new object is creates its member variables are created.
What about member functions? Member function are not allocated news there is always one copy of all member function. By default a member variable is added to every member function that is this pointer which is pointing to the object itself.
When there is no object present that is object pointer is null value. It doenst matter because you are not accesssing it any way. You will get in problems if you use this pointer of any of the member variable in the method. This is because member variable are not valid in case of null pointer.
in MFC we have GetSafeHwnd() method for CWnd. This works on same principle.