I came across a very strange behaviour using G++ (4.5.2) on different platforms; here’s the code :
class Class
{
private:
std::string rString;
public:
Class()
{
this->rString = "random string";
std::cout << "Constructor of Class" << std::endl;
}
virtual ~Class()
{
std::cout << "Destructor of Class" << std::endl;
}
void say() const
{
std::cout << "Just saying ..." << std::endl;
if (this == NULL)
std::cout << "Man that's really bad" << std::endl;
}
void hello() const
{
std::cout << "Hello " << this->rString << std::endl;
}
};
int main()
{
Class *c = NULL;
/* Dereferencing a NULL pointer results
in a successful call to the non-static method say()
without constructing Class */
(*c).say(); // or c->say()
/* Dereferencing a NULL pointer and accessing a random
memory area results in a successful call to say()
as well */
c[42000].say();
/* Dereferencing a NULL pointer and accessing a
method which needs explicit construction of Class
results in a Segmentation fault */
c->hello();
return (0);
}
The question is, why the two first statements in the main function don’t crash the program? Is this undefined behaviour, or the compiler is simply calling Class::say() as if it was static since it doesn’t dereference “this” pointer inside the method?
Yes, it’s undefined behavior. You cannot call a member function with a null pointer.
In practice, the first two indeed work because
thisis never dereferenced so your undefined behavior doesn’t have to manifest like it does in the third, where memory is indeed wrongly accessed.(In all cases, you die a little inside each time it’s called, so don’t do that.)