Dereferencing a null-pointer allowed?

L

Lutz Richter

Hi,

given the following code:

-----------------------------
class B
{
public:
B(): Value(99) {}
int Get() { if (this) return Value; else return -1; }

private:
int Value;
};

int main()
{
B* b = 0;
cout << b->Get();
}
-----------------------------


I wonder if this is allowed. I did not have any problem with any
compiler yet. It works! But is this guaranteed?

Unfortunately Stroustrop & Co. do not mention this problem in their
books. If anyone has a documentation about NOT doing the above example,
then please tell me.

Thanks in advance, Lutz.
 
P

Phlip

Lutz said:
B* b = 0;
cout << b->Get();
}
I wonder if this is allowed. I did not have any problem with any
compiler yet. It works! But is this guaranteed?

Nope; pure undefined behavior occurs when you access 'b's value. b-> is
really (*b)., and the undefined behavior occurs at *b time.

"Undefined behavior" means anything can happen and it's not your compiler's
fault. The code could appear to work correctly, it could alternately work
and not work, or it could make the nearest toilet explode.
 
D

dave_mikesell

Hi,

given the following code:

-----------------------------
class B
{
public:
B(): Value(99) {}
int Get() { if (this) return Value; else return -1; }

private:
int Value;

};

int main()
{
B* b = 0;
cout << b->Get();}

I often smoke while feuling my car. No explosions yet!
 
S

Salt_Peter

Hi,

given the following code:

-----------------------------
class B
{
public:
B(): Value(99) {}
int Get() { if (this) return Value; else return -1; }

private:
int Value;

};

int main()
{
B* b = 0;
cout << b->Get();}

-----------------------------

I wonder if this is allowed. I did not have any problem with any
compiler yet. It works! But is this guaranteed?

Unfortunately Stroustrop & Co. do not mention this problem in their
books. If anyone has a documentation about NOT doing the above example,
then please tell me.

Thanks in advance, Lutz.

No, as already mentioned - its undefined behaviour.
The pointer B* b is just a pointer, it points to a 'black hole' (tm)
until such time that the pointer's value is made to point to an object
(that means a ctor was invoked one way or another).
B* p_b; // does not invoke a ctor
Your code *should* be generating a segmentation fault, and it would if
you remove the if condition. Bypassing the compiler's ability to help
you code is bad karma.

#include <iostream>

class B
{
...
public:
B(): value(99) { std::cout << "B()\n"; }
B(const B& copy)
{
Value = copy.Value;
std::cout << "B copy ctor\n";
}
...
};

and there is no need to 'new' anything either:

int main
{
B b; // invokes ctor
B* p_b = &b;
std::cout << p_b->Get() << std::endl;
}
 
J

James Kanze

given the following code:
-----------------------------
class B
{
public:
B(): Value(99) {}
int Get() { if (this) return Value; else return -1; }
private:
int Value;
};
int main()
{
B* b = 0;
cout << b->Get();}

I wonder if this is allowed.

Definitly not. b->f() is the same as (*b).f(), and *b
dereferences a null pointer.
I did not have any problem with any
compiler yet. It works! But is this guaranteed?

Try uping the optimization. A good compiler will know that
"this" can never be null, and optimize out the test, always
executing the true branch. Throw in multiple inheritance or
virtual functions, and there's a good chance that the code will
core dump even without optimization.
Unfortunately Stroustrop & Co. do not mention this problem in their
books.

You mean that they don't say that you're not allowed to
dereference a null pointer? Or that they don't explain that
"p->" is the equivalent of "(*p)".
If anyone has a documentation about NOT doing the above example,
then please tell me.

According to the standard, "p->" is the equivalent of "(*p)",
"*p" is the dereferencing operator, and dereferencing a null
pointer is undefined behavior.
 
J

James Kanze

Because that has nothing to do with undefined behavior. UBs are more
dangerous. :)

I think his point was that just because nothing bad has happened
yet, that doesn't prove that it's safe.
 
S

Sarath

Hi,

given the following code:

-----------------------------
class B
{
public:
B(): Value(99) {}
int Get() { if (this) return Value; else return -1; }

private:
int Value;

};

int main()
{
B* b = 0;
cout << b->Get();}

-----------------------------

I wonder if this is allowed. I did not have any problem with any
compiler yet. It works! But is this guaranteed?

Unfortunately Stroustrop & Co. do not mention this problem in their
books. If anyone has a documentation about NOT doing the above example,
then please tell me.

Thanks in advance, Lutz.

I've posted an entry in my blog regarding this

http://sarathc.wordpress.com/2007/01/13/why-this-program-is-not-crashing-up/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top