Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Null reference

Reply
Thread Tools

Null reference

 
 
David W
Guest
Posts: n/a
 
      07-18-2006
I'm almost tearing my hair out. A colleague claimed that a null reference can exist, like
this:

void f( int& p )
{
printf( "%d\n", p );
}

int main (int argc, char *argv[])
{
int*p= NULL;

f( *p );

return 0;
}

I pointed him to the relevant part of the C++ standard that forbids this in a well-defined
program, but he countered that in the "real world" a reference can be "null". An argument
then ensued in which he managed to raise concerns with two other colleagues because the
crash in the above code is likely to occur where the reference is used, which could be
anywhere, not where the null pointer is dereferenced. One (who has had little experience
with C++) even said that references "shouldn't be used in safety critical code". The other
became concerned because he'd always assumed that a reference has to refer to a valid
object, and now he wonders whether he should test for a "null reference", at least with an
assert, wherever a function takes a reference parameter.

I've tried everything I can think of to return to some sanity, but to no avail. I've told
them:
- That the problem in the code above is not the reference but the dereference of a null
pointer, which is a normal bug that everyone knows to avoid.
- That I can't recall actually coming across a "null reference" bug in a real program in
over a decade of using C++
- That there are a million things you can do that can cause undefined behaviour, so why be
specifically concerned about this one?
- That there are a multitude of ways that a bug can manifest itself long after the code
that caused it executes (e.g., keep a pointer to an object that is subsequently deleted),
so why be specifically concerned about this one?

They are still not convinced that the "null reference" is not a potential problem that
deserves some attention, and I'm looking for ideas as to what else I can say to get it off
the radar completely, where it belongs (that's if the people here agree with me of
course).

David


 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      07-18-2006
* David W:
> I'm almost tearing my hair out. A colleague claimed that a null reference can exist, like
> this:
>
> void f( int& p )
> {
> printf( "%d\n", p );
> }
>
> int main (int argc, char *argv[])
> {
> int*p= NULL;
>
> f( *p );
>
> return 0;
> }
>
> I pointed him to the relevant part of the C++ standard that forbids this in a well-defined
> program, but he countered that in the "real world" a reference can be "null". An argument
> then ensued in which he managed to raise concerns with two other colleagues because the
> crash in the above code is likely to occur where the reference is used, which could be
> anywhere, not where the null pointer is dereferenced. One (who has had little experience
> with C++) even said that references "shouldn't be used in safety critical code". The other
> became concerned because he'd always assumed that a reference has to refer to a valid
> object, and now he wonders whether he should test for a "null reference", at least with an
> assert, wherever a function takes a reference parameter.
>
> I've tried everything I can think of to return to some sanity, but to no avail. I've told
> them:
> - That the problem in the code above is not the reference but the dereference of a null
> pointer, which is a normal bug that everyone knows to avoid.
> - That I can't recall actually coming across a "null reference" bug in a real program in
> over a decade of using C++
> - That there are a million things you can do that can cause undefined behaviour, so why be
> specifically concerned about this one?
> - That there are a multitude of ways that a bug can manifest itself long after the code
> that caused it executes (e.g., keep a pointer to an object that is subsequently deleted),
> so why be specifically concerned about this one?
>
> They are still not convinced that the "null reference" is not a potential problem that
> deserves some attention, and I'm looking for ideas as to what else I can say to get it off
> the radar completely, where it belongs (that's if the people here agree with me of
> course).


It's formally undefined behavior to dereference a nullpointer.

But it can happen, and the result of using that reference is that Bad
Things Happen.

Another way to obtain an invalid reference is to destroy an object that
some other part of the code holds a reference to (the simplest way to do
this is to return a reference to a local variable), which yields a
dangling reference.

References don't buy you technical safety: null-references and dangling
references can exist -- but null-references can't exist in a valid
program, and dangling references can't be used in a valid program.

Instead of technical safety references buy you simplicity and clear
/communication of intent/, i.e. this is intended to never be null, plus
the possibility of unified notation (e.g. indexing, which can be applied
in template code), all which in turn buys you safety and productivity.

When your function is passed a null-reference or dangling reference you
know that it's an error in the calling code. When a null-pointer or
dangling pointer occurs you don't necessarily know that it's an error in
the calling code. Perhaps you need to handle null-pointers (and the
result is messy checking and deciding what to do or not in that case,
which complicates things, and leads to more of the same, more bugs).

Summing up, your first colleague was right that null-references can
exist, but not that they can exist in a valid program. And you were
right that that situation almost never occurs in practice. Because
apart from simpler notation, the point of a reference is to communicate
that it's intended to never be null or otherwise invalid, so nobody will
try to set it to null-reference.

Your colleague who maintained that references shouldn't be used in
safety-critical code got it exactly backwards.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
 
 
 
David W
Guest
Posts: n/a
 
      07-18-2006
"Alf P. Steinbach" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)...
>
> It's formally undefined behavior to dereference a nullpointer.
>
> But it can happen, and the result of using that reference is that Bad
> Things Happen.
>
> Another way to obtain an invalid reference is to destroy an object that
> some other part of the code holds a reference to (the simplest way to do
> this is to return a reference to a local variable), which yields a
> dangling reference.
>
> References don't buy you technical safety: null-references and dangling
> references can exist -- but null-references can't exist in a valid
> program, and dangling references can't be used in a valid program.
>
> Instead of technical safety references buy you simplicity and clear
> /communication of intent/, i.e. this is intended to never be null, plus
> the possibility of unified notation (e.g. indexing, which can be applied
> in template code), all which in turn buys you safety and productivity.


Good point.

> When your function is passed a null-reference or dangling reference you
> know that it's an error in the calling code. When a null-pointer or
> dangling pointer occurs you don't necessarily know that it's an error in
> the calling code. Perhaps you need to handle null-pointers (and the
> result is messy checking and deciding what to do or not in that case,
> which complicates things, and leads to more of the same, more bugs).
>
> Summing up, your first colleague was right that null-references can
> exist,


Well, actually this started when I asked an interviewee what the differences were between
pointers and references, and he said that one difference was that a reference couldn't be
null. After the interview my colleague claimed that he was wrong. In the context of the
interview - pure C++ questions without considering the usual implementation on actual
compilers - I would say that my colleague was wrong.

> but not that they can exist in a valid program. And you were
> right that that situation almost never occurs in practice. Because
> apart from simpler notation, the point of a reference is to communicate
> that it's intended to never be null or otherwise invalid, so nobody will
> try to set it to null-reference.


Good point.

> Your colleague who maintained that references shouldn't be used in
> safety-critical code got it exactly backwards.


Thank you.

David


 
Reply With Quote
 
Frederick Gotham
Guest
Posts: n/a
 
      07-18-2006
David W posted:


> They are still not convinced that the "null reference" is not a
> potential problem that deserves some attention, and I'm looking for
> ideas as to what else I can say to get it off the radar completely,
> where it belongs (that's if the people here agree with me of course).



You are correct. Your colleagues are wrong. Plain and simple.

(1) It's undefined behaviour to dereference a null pointer.
(2) It's undefined behaviour to have a null reference.

What you and your colleagues need to debate is NOT whether a null reference
is a good thing, but rather whether you want to write portable, Standard
C++-compliant code.

At the moment, it is NOT portable, Standard C++-compliant code.

If you want some sort of null reference maybe try something like:


struct AlignedByte {

char unsigned * const p;

AlignedByte() : p(new char unsigned) {}

~AlignedByte() { delete p; }

} aligned_byte;

template<class T>
inline T &NullRef()
{
return reinterpret_cast<T&>(*aligned_byte.p);
}

template<class T>
inline bool IsNull(T &ref)
{
return reinterpret_cast<char unsigned const*>(&ref) == aligned_byte.p;
}

/* Here comes the usage demonstration code */

#include <string>
using std::string;

void SomeFunc(string &arg)
{
if (IsNull(arg)) return;

arg += "success";
}

int main()
{
string obj = "doctor";

SomeFunc(obj);

SomeFunc( NullRef<string>() );
}


--

Frederick Gotham
 
Reply With Quote
 
Frederick Gotham
Guest
Posts: n/a
 
      07-18-2006
Frederick Gotham posted:

> string obj = "doctor";



Opps, I was typing quickly and got carried away. I would never use that form
of initialisation for a class type, but rather:

string obj("doctor");


--

Frederick Gotham
 
Reply With Quote
 
Michiel.Salters@tomtom.com
Guest
Posts: n/a
 
      07-18-2006
Frederick Gotham wrote:
> David W posted:
>
> > They are still not convinced that the "null reference" is not a
> > potential problem that deserves some attention, and I'm looking for
> > ideas as to what else I can say to get it off the radar completely,
> > where it belongs (that's if the people here agree with me of course).

>
> You are correct. Your colleagues are wrong. Plain and simple.
>
> (1) It's undefined behaviour to dereference a null pointer.
> (2) It's undefined behaviour to have a null reference.


No, there is no such thing a a "null reference" so it cannot be
undefined
behavior to have one. There are no such things as invisible pink
unicorns
in ISO C++ either, and therefore they aren't undefined behavior either.

Once you have undefined behavior in a C++ program, it stops being a
program that you can describe in standard C++ terms. "reference" in
this context is definitely a standard term, and doesn't apply anymore.
The best way to describe what actually happens at that point is
assembly terminology. E.g. one can talk about a SEGV.

HTH,
Michiel Salters

 
Reply With Quote
 
Frederick Gotham
Guest
Posts: n/a
 
      07-18-2006
Michiel posted:


<snip wordplay>


--

Frederick Gotham
 
Reply With Quote
 
=?ISO-8859-15?Q?Juli=E1n?= Albo
Guest
Posts: n/a
 
      07-18-2006
David W wrote:

> void f( int& p )
> {
> printf( "%d\n", p );
> }
>
> int main (int argc, char *argv[])
> {
> int*p= NULL;
>
> f( *p );
>
> return 0;
> }


> in safety critical code". The other became concerned because he'd always
> assumed that a reference has to refer to a valid object, and now he
> wonders whether he should test for a "null reference", at least with an
> assert, wherever a function takes a reference parameter.


A better solution can be:

void f (int * p)
{
assert (p != 0); // Or throw an exception, or both
int & ref= * p;
(....)
}

With constructs like that, isolate the parts of the code that uses
references from the parts where pointers can be used without care.

Of course, is better to never use pointers without care.

--
Salu2
 
Reply With Quote
 
Noah Roberts
Guest
Posts: n/a
 
      07-18-2006

David W wrote:
> They are still not convinced that the "null reference" is not a potential problem that
> deserves some attention, and I'm looking for ideas as to what else I can say to get it off
> the radar completely, where it belongs (that's if the people here agree with me of
> course).


This is just something I've come to expect in the world of
proffessional programming. I've often run into brick walls in
arguments I think should be cut and dry. For instance whether to make
use of exceptions (argument against is that they are "slow" and cost
extra even when not fired - yet we have to use the stdlib so we pay all
costs anyway...I digress), or making use of boost and the stdlib (I
used to have to justify every use of the stdlib classes vector and
string to the lead - less and less now but it is still annoying..we
still don't use boost because we don't use "3rd party libraries" (ask
me how many wheels I've invented)).

I've just grown to expect that people have their own oppinions and
quite often those oppinions are based on outdated facts or just plain
ignorance to the real facts. It's not worth fighting beyond explaining
the facts and letting the descision get made. If they want to pay you
to go around and change all references to pointers and place asserts
then so be it. If they want to cripple their ability to write secure
code to get secure code then it's not your place to do otherwise unless
you are the lead; just like I'm often crippling the compiler's ability
to optimize and being slow to develop by reinventing "fast" code all
the damn time. I try to convince them that I'm not smarter than the
compiler writers or the people who wrote our implementation's stdlib
but they consistantly expect me to be and consistantly keep me from
using good abstractions because they have some idea that they won't be
efficient - no, no profiling occurs.

When someone asks you why your code is inefficient and error prone you
can explain that you could have done better if you weren't stuck with a
crippled version of the language...assuming you can show this. Just
document every case where you could have done a better or faster job
given the right tools. You might also consider getting your resume
together again before you get a bunch of bad habits in you; I've been
putting mine together as I want to find some place where there are
people I can learn from and I feel I have reached an upper limit of
learning at my current job.

Teamwork is nice. I like working in teams instead of alone; for the
most part I like the team I am in. But sometimes you have to do stupid
things because that is what the team decides...even though that might
just be one or two people with bigger salaries than you and the rest of
the team. So, I've said my piece and you seem to have said yours. The
other side's argument might be dumb, and in this case it certainly is,
but there isn't much that can be done...they don't seem convincable in
either of our situations. That's life.

 
Reply With Quote
 
Noah Roberts
Guest
Posts: n/a
 
      07-18-2006

Noah Roberts wrote:
> they don't seem convincable in
> either of our situations. That's life.


Of course, you could ask them how you are supposed to overload
operators without using references. If they want to remove references
then you can't and you can mention the crippling of the entire std
library (most containers and algorithms will be unusable). If they
want to use references only where it has to be done then ask them what
steps will need be taken to assure that their "safety concerns" are
addressed in those rather common cases. Once that is done ask them why
they don't just use those steps anywhere a reference is used instead of
making policy that they are never used.

By making them face the fact that they have to use references or
reinvent the entire standard library you should be a long way toward
winning them over. Then by making them explain what would be needed to
make references safe they will likely convince themselves that they
already are and you'll start checking your pointers before turning them
into references.

If that doesn't work, nothing will.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
createImage sometime returns null and sometime returns non-null. vizlab Java 3 10-17-2007 11:21 AM
"stringObj == null" vs "stringObj.equals(null)", for null check?? qazmlp1209@rediffmail.com Java 5 03-29-2006 10:37 PM
difference between null object and null string gokul.b@gmail.com Java 16 10-12-2005 06:43 PM
VB.NET Null to SQL Null (ASP.NET 2.0 GridView) Kivak Wolf ASP .Net 2 06-28-2005 02:01 PM
Is there a null ostream (like /dev/null) in cpp? Bo Peng C++ 13 07-18-2004 07:17 PM



Advertisments