www.digitalmars.com         C & C++   DMDScript  

c++ - strange behaviour (vs cpp compiler bug !?). call on null pointer succeeds.

reply "andrew" <user earth.com> writes:
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;
}
Jan 09 2007
parent reply Bertel Brander <bertel post4.tele.dk> writes:
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
Jan 09 2007
parent reply "andrew" <user earth.com> writes:
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 
Jan 09 2007
parent "Paul McKenzie" <paulm dynasoft.com> writes:
"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
Jan 10 2007