C++ references are aliases. The effect of this is that dereferences to pointers don't necessarily happen where they appear, they happen where they are evaluated. Taking a reference to an object doesn't evaluate the object, it aliases it. Using the reference is what evaluates the object. C++ cannot guarantee references are valid; if it does, all C++ compilers are broken. The only way to do so is to eliminate all possiblity of dynamic allocation with references. In practice, the assumption is that a reference is a valid object. Since *NULL is undefined & invalid, it follows that for p = NULL, *p is also undefined. The problem with C++ is *p will be effectively passed to a function, or delayed in its evaluation until which time the reference is actually used. Arguing that it is undefined is not the point of the asker's question. If it were illegal, the compiler would enforce it, and so would the standard. Neither does, that I am aware of.
int &r = *j; // aliases *j, but does not evaluate j
if(r > 0) // evaluates r ==> *j, resulting in dereference (evaluate j) at this line, not what some expect
;
1) You can test a reference for aliasing a NULL pointer, &r is simply &(whatever r aliases to) (EDIT)
2) When passing a "dereferenced" pointer (*i) as a reference parameter, the dereference doesn't happen at the callsite, it may never happen, because it is a reference (references are aliases, not evaluations). That is the optimization of references. If they were evaluated at the callsite, either the compiler is inserting extra code, or it would be a call by value and less performant than a pointer.
Yes, the reference itself is not NULL, it is invalid, just as *NULL is invalid. It is the delaying of evaluation of dereference expressions that is not consistent with claiming it is impossible to have an invalid reference.
#include <iostream>
int fun(int & i) {
std::cerr << &i << "\n";
std::cerr << i << "\n"; // crash here
}
int main() {
int * i = new int();
i = 0;
fun(*i); // Why not crash here? Because the deref doesn't happen here, inconsistent, but critical for performance of references
}
EDIT: Changed my example as it has been misconstrued as suggestion for testing references, not what I wanted to demonstrate. I only wanted to demonstrate the invalid reference.