Asked By Doug Harrison [MVP]
19-Jun-07 12:03 PM

On Mon, 18 Jun 2007 22:21:23 -0500, "Ben Voigt [C++ MVP]"
It's a fallacy to try to deal with wild pointers in terms of C++
exceptions. It would be OK (but strange) for a function that takes a
pointer to document it throws an exception when passed a NULL pointer.
That's well within the tradition of C. In C++, you can use references to
express that in code. It's also well within the tradition of C++,
considering that STL algorithms are defined on iterators, pointers are
iterators, and requirements include valid iterator ranges.
You have a point about robustness, in that it is typically possible to
create a reference bound to NULL. However, to do that requires that you
dereference a NULL pointer, and someone who can't get that right is just as
likely to pass wild pointers to pointer parameters, which can't be detected
in code, at least not with any reliability. On the other hand, someone who
can get this stuff right can use references correctly, and I don't think
consideration of the lowest common denominator should prohibit him from
using what is for him and like people a language feature that provides
increased elegance. (It's not going to provide much in the way of increased
robustness, because modulo the rare mistake, he was using pointers
correctly to begin with.)
I thought that the first six months I used C++, but then I realized I
shouldn't be forming expectations without having looked at the actual
functions and types involved. For example:
void f(int* p) { *p = 2; }
void g(int* x)
{
f(x);
}
Often, I'm interested in whether or not f(x) modifies *x, and I can't tell
that without looking at the code or consulting the documentation. Once I
realized that, I stopped thinking of f(&x) as providing a valuable
call-site clue. I've never regretted that shift in thinking.
As for when *not* to use references, don't use a const reference parameter
in a ctor and use it to initialize a const reference class member variable.
Since const references accept temporaries, it's far too easy to bind a
temporary to a reference such that the temporary doesn't outlive the
reference. It's OK to use non-const references in this context, with the
documentation caveat that the lifetime of the referent must outlive the
object's use of it. A good example of this is a lock class that takes a
reference to a mutex.
--
Doug Harrison
Visual C++ MVP