Sign in to follow this  
  • entries
    375
  • comments
    1136
  • views
    297486

A thingy

Sign in to follow this  
superpig

83 views

This occured to me earlier:

Dereferencing a null pointer usually ends up in an access violation - you either try to read from or write to the guard page, which stops you (with a thump).

However, if you're not actually reading from / writing to that null pointer, you're OK.

Member functions in C++ aren't actually "part of" the objects you kick around - they're named as such, but they're just like regular functions - chunks of code in memory somewhere. How is it that you can call a function on some particular object? Because C++ passes a hidden parameter to your member functions - the 'this' pointer - which lets it know which object it's currently "part of."

So when you dereference a pointer to an object and call a regular, nonvirtual function on it, the compiler turns that call into a "push this, call fn" setup. The function itself is well defined and exists in memory, always. The thing that's actually null is the 'this' pointer.

Which means that you should be able to catch some dereferencing-a-null-pointer errors like so:

void SomeObject::SomeFunction()
{
assert(this, "Tried to call SomeFunction() on a NULL SomeObject!");
stuff
}

Possibly more usefully:

int SomeObject::SomeOtherFunction()
{
if(!this) return DEFAULT_VALUE;
stuff
}

It's filthy and disgusting and I love it. It can make some of those multiple levels of indirection easier to handle:


this:

Object* pxObject = GetObject();
if(pxObject)
{
OtherObj* pxOtherObj = pxObject->GetOtherObject();
if(pxOtherObj)
{
pxOtherObj->DoWork();
}
}

can become this:

GetObject()->GetOtherObject()->DoWork();

if Object::GetOtherObject and OtherObj::DoWork can handle this being == NULL.



It won't work on virtual functions. Virtual functions are called by dereferencing 'this' (which dies) to look up the function address in the vtable. If the function is virtual it will die before it gets a chance to check the value of 'this'.

Washu and/or muer and/or Fruny are going to kill me.
Sign in to follow this  


3 Comments


Recommended Comments

The CWnd::GetSafeHandle() method in the MFC uses this trick. The assert is probably better - how a call to a method of a null object can be correct? It will more probably hide an horrid bug :)

Regards,

Share this comment


Link to comment
.NET Beta 1 (the one released in early 2001) had this bug.

You could create a null object, then proceed to call methods off it anyway.

If you tried to access a member variable or call a virtual function, it would throw NullReferenceException. But as long as you didn't, it would work.

That confused me.

Mark

Share this comment


Link to comment

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