Thread overview
strange behaviour (vs cpp compiler bug !?). call on null pointer succeeds.
Jan 09, 2007
andrew
Jan 10, 2007
Bertel Brander
Jan 10, 2007
andrew
Jan 10, 2007
Paul McKenzie
January 09, 2007
Hi,
This behaviour made me spend some time trying to figure out what's happening
in the project Im working on.
But putting it in a simple test it has the same behaviour.

You have 2 simple classes. One has a public method. The other one has a
member data as a pointer to the first class.
I initialize on the ctor the pointer to NULL. Even so, when calling the
first class' method through the pointer, it works !
I cant believe it works. If you look at the assembly code, it looks like the
method is found without a problem, nothing weird.

I tested on 3 computers and it works (Windows XP SP2).
Compiler: Visual Studio 2003 and 2005.


// UnInstantiated.h
#pragma once

class CUnInstantiated
{
public:
 CUnInstantiated(void) { m_nValue = 1; }
 void Boo()
 {
      // this will work
      printf("Boo");

      // this will do access violation
      //printf("Boo ! %d", m_nValue);
 }

 int m_nValue;
};


// user.h
#pragma once
#include "UnInstantiated.h"

class CUser
{
public:
 CUser(void) { pNULLPointer = NULL; }
 void Do() { pNULLPointer->Boo(); }

private:
 CUnInstantiated* pNULLPointer;
};


// main.cpp
#include "stdafx.h"
#include "User.h"

int _tmain(int argc, _TCHAR* argv[])
{
 CUser user;
 user.Do();

 return 0;
}




January 10, 2007
andrew skrev:
> Hi,
> This behaviour made me spend some time trying to figure out what's happening
> in the project Im working on.
> But putting it in a simple test it has the same behaviour.
> 
> You have 2 simple classes. One has a public method. The other one has a
> member data as a pointer to the first class.
> I initialize on the ctor the pointer to NULL. Even so, when calling the
> first class' method through the pointer, it works !
> I cant believe it works. If you look at the assembly code, it looks like the
> method is found without a problem, nothing weird.

There is no reason why it should not work, you should however not
rely on it.

You never use pNULLPointer to access anything, Boo is just
a function as any other.

If you change the printf line to:
      printf("Boo: %p\n", this);

It will correctly print:
  Boo: 0

Notice that Boo could have been a static function.

If you try to access the object through the pointer (either through
pNULLPointer or this) it will fail.

-- 
Just another homepage:
http://damb.dk
But it's mine - Bertel
January 10, 2007
I agree with you, its not reliable.
I know that method are just like any other functions internally but I dont
agree 100% that 'there is no reason why it should not work'.

What if Boo( ) would do something which i dont expect to be done if the CUnInstantiated is not instantiated (from the logical point of view i mean). Calls on an invalid pointer (bad memory) are expected NOT to be working. Again, I do know that methods are like any other functions but its very misleading.

This means ANY function from CUnInstantiated will work (as long it does not use members of CUnInstantiated of course):

pNULLPointer->Boo();
pNULLPointer->Boo1();
 ....

Like you said its not reliable of course. But the fact that it is working today on my machines will make the bug get away.

thank you


January 10, 2007
"andrew" <user@earth.com> wrote in message news:eo25ai$1nc2$1@digitaldaemon.com...
> I agree with you, its not reliable.
> I know that method are just like any other functions internally but I dont
> agree 100% that 'there is no reason why it should not work'.
>
> What if Boo( ) would do something which i dont expect to be done if the
> CUnInstantiated is not instantiated (from the logical point of view i
mean).
> Calls on an invalid pointer (bad memory) are expected NOT to be working. Again, I do know that methods are like any other functions but its very misleading.
>
> This means ANY function from CUnInstantiated will work (as long it does
not
> use members of CUnInstantiated of course):
>
> pNULLPointer->Boo();
> pNULLPointer->Boo1();
>  ....
>
> Like you said its not reliable of course. But the fact that it is working today on my machines will make the bug get away.

In C++, accessing a null pointer is *undefined behaviour*.  It may work, it may not work, it may crash, it may not crash, your machine can reboot itself, etc.  It is up to you to see that you are not invoking undefined behaviour, so it isn't a problem with the compiler.  There is no reason why the compiler must crash at all -- its undefined what will happen.

Another example -- there are compilers that will not let you get away with using "delete" when you allocated with "new[]", even on simple types (a crash occurs).  Does this mean that the Visual C++ compilers are incorrect because it seems that "delete" works with "new[]" for simple types?  Of course not, because using the wrong form of  "delete" is undefined behaviour.

The only things that are certain to "crash", i.e. throw an exception, are those operations defined in the ANSI C++ standard to throw an exception, for example vector::at( ) or doing a dynamic_cast on a reference that isn't of the base type.   NULL pointer accesses are not in the list of guarantees.

Paul