Sign in to follow this  
lride

Calling member function via nullptr

Recommended Posts

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

Is this undefined behavior?

Share this post


Link to post
Share on other sites

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.

Edited by Paradigm Shifter

Share this post


Link to post
Share on other sites
Brother Bob    10344

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.

Share this post


Link to post
Share on other sites

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 ;)

Edited by Paradigm Shifter

Share this post


Link to post
Share on other sites
lride    674

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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
Bearhugger    1276

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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this