What I'm saying is that for code like:
void fn(int* p)
{
WaitForSingleObject(semaphore);
*p++;
ReleaseSemaphore(semaphore);
}
Clearly the above is not exception safe, and if p is NULL or otherwise
invalid to cause an access violation, you will leak semaphore counts. To
say that null and invalid references don't exist suggests that if you
would just change (int* p) to (int& i) the function would be unable to
fail and therefore correctly manages the semaphore, but this is a bogus
argument. The reference version of the function can still throw an access
violation and still needs to be coded for exception safety. This is what
I mean when I say that people who use references to avoid the problems
associated with invalid pointers are misinformed.
According to the standard (8.3.2[4])
"... a null reference cannot exist in a well-defined program, because the
only way to create such a reference would be to bind it to the "object"
obtained by dereferencing a null pointer which causes undefined
behaviour".
I understand your point but your own argument is what's "bogus". As soon
as you engage in undefined behaviour then all bets are off. If you define
the above function as taking a reference arg then the undefined behaviour
occurs the moment someone tries to dereference an invalid pointer. That
has nothing to do any function you may be calling at the time. The
undefined behaviour occurs before the function has even started so how can
it protect itself. There is no valid way. Everything might blow up before
the function even begins but the entire environment should be considered
corrupt even if it does start. Your attempt to "protect" the function
would therefore be unreliable but that's beside the point. An "invalid
reference" doesn't exist which is the point. Null pointers do however. So
do invalid pointers which are legal so long as you don't dereference them.
The pointer version of the function would therefore have to protect itself
while the reference version has nothing to protect itself against (since
invalid references don't exist). Even for the pointer version however, it
can't protect itself against an invalid (non-null) pointer using any
standard technique noting that an "access violation" isn't even
guaranteed. Nothing is guaranteed and standard C++ can't even catch these
types of so-called "exceptions". A reference parameter is therefore
inherently safe unlike a pointer parameter since null references don't
exist so a reference parameter can never refer to an invalid object by
definition. Pointers legally can however so dereferning an invalid pointer
isn't safe (which is your point) but that has nothing to do with passing
the dereferenced value as a reference arg. I therefore suggest that you're
the one who's misinformed.