Calling member function via nullptr

Started by
6 comments, last by Bearhugger 11 years ago

class A{   
void say(){std::cout<<"hi";}
};
 
int main()
{
    A * a=nullptr;
    a->say();   //no crash, works fine
}
 

Is this undefined behavior?

An invisible text.
Advertisement

Not sure.

It's safe because it doesn't use the this pointer and isn't virtual. It would be better off being static though, as soon as you use the this pointer or make it virtual it will crash.

Non-static member functions are just name mangled functions which have an implicit this pointer passed as an argument.

EDIT: i.e. there is no pointer derefernce going on. It just compiles to CallSomeNameMangledFunction(nullptr); Virtual functions are different they compile to this->vtbl.VirtualFunc(this); so there is a dereference going on.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley
Although what Paradigm Shifter says is in practice what will happen, the standard says doing this is undefined behavior. Just don't do it.

It is undefined. The -> operator is defined in terms of a dereference and the . operator, so you are clearly dereferencing a null pointer which is undefined behavior.

From a practical implementation point of view, no actual memory access may be performed to actually cause a crash, but your code is nevertheless ill-defined.

I'll bow to others knowledge about it being undefined.

The simple and obvious implementation however shouldn't dereference anything at the point of calling the function. Inside the function you are toast if you do dereference this.

I could imagine some implementations doing some extra work (maybe in a debug configuration) which does attempt to use the this pointer for a simple member function call (logging, etc.).

Don't do it anyway, it's asking for trouble.

EDIT: And the code posted shouldn't compile ;) A::say isn't public ;)

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

From a practical implementation point of view, no actual memory access may be performed to actually cause a crash, but your code is nevertheless ill-defined.

I think this is why it doesn't crash... If I use a member variable inside the function, it crashes

An invisible text.

If it doesn't crash when calling it with a nullptr, you should question whether it should be a member function at all ;) You may as well write a global SayHi function since it doesn't use any of the functionality of a class A at all.

You could make it static but then again it doesn't need any knowledge of the internal representation/implementation of an A either, and it may be useful to non-A's.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

It doesn't crash because the say() method doesn't need to dereference the this pointer. The method might as well be a static method when you think about it. In fact the optimizer probably compiles it as a static method since there's no need to pass the this pointer.

Try changing the method so that it loads a member variable though. Or try calling the method through a pointer to an instance method. (The ->* and .* operators.) Now you're probably asking for trouble.

This topic is closed to new replies.

Advertisement