Jump to content
  • Advertisement
Sign in to follow this  
lride

Calling member function via nullptr

This topic is 1939 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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
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.

Edited by Paradigm Shifter

Share this post


Link to post
Share on other sites
Although what Paradigm Shifter says is in practice what will happen, the standard says doing this is undefined behavior. Just don't do it.

Share this post


Link to post
Share on other sites

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

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

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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!