Null references.

J

jason.cipriani

Is it OK to dereference NULL pointers if the only thing you are doing
is storing them in a reference then comparing addresses to NULL again
later, as in:

=== BEGIN EXAMPLE ===

Something g_something;

const Something & getSomething () {
if (condition)
return g_something;
else
return *(const Something *)NULL; // <--- !!!
}

void function () {
const Something &s = getSomething;
if (&s == NULL) { // <--- !!!
// ...
} else {
// ...
}
}

=== END EXAMPLE ===

Thanks,
Jason
 
J

jason.cipriani

* (e-mail address removed):


No.

That incurs Undefined Behavior.

Then, if this is undefined:

Something &ref = *(Something &)NULL;

Doesn't that mean this also undefined?

Something *ptr = NULL;
Something &ref = *ptr;

And if so, then that also means this is undefined, as the possibility
exists for the pointer to be NULL?

Something * function ();
Something *ptr = function();
Something &ref = *ptr;

And if that is undefined, is this the cleanest way to make sure
nothing undefined happens?

Something * function ();
Something *ptr = function();
if (ptr) {
Something &ref = *ptr;
// ...
} else {
// error
}

Also, unrelated to references, just out of curiosity, does that mean
statements like this are also undefined:

Something *ptr = &(*(Something *)NULL);

Thanks,
Jason
 
J

jason.cipriani

Depends on whether the pointer actually can be 0. It's the actual dereferencing
of a nullpointer that incurs Undefined Behavior. Not the potential.

Oh, I guess that makes sense.

Thanks for the good response and explanation.

Jason
 
J

James Kanze

There are some exceptions to incurring UB for dereferencing a
nullpointer. The most important one is that any given compiler
vendor can decide to give that a well-defined meaning at
compile time for that compiler, and exploit that to implement
various macros in the standard library. Another one is the
context of a typeid call.

Hows that?

Modulo vendor specific guarantees (of course), it's undefined
behavior to dereference a null pointer in code that actually
gets executed. Something like sizeof( *p ) is fine, even if p
is a null pointer. But typeid normally requires execution,
e.g.: typeid( *p ) is undefined behavior if p is a null pointer
(and the pointed to object has a polymorphic type, but then,
that's the usual reason for using typeid).
 
J

James Kanze

* James Kanze:
I'm sorry, that's incorrect. §5.2.8/2, typeid guarantees to
throw a std::bad_typeid exception if you give it an lvalue
formed by dereferencing a nullpointer to polymorphic type. So
we're out of UB-land and into guaranteed exception-land. :)

Interesting. A bit strange, but who's to complain. Anything
which reduces undefined behavior is good.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top