Consider this code:
class Addressable;
class Class1 { void foo(Addressable &a) { (void) &a; } }; // OK
class Addressable { void *operator &() { return this; } };
class Class2 { void foo(Addressable &a) { (void) &a; } }; // Error: operator & private
Why does C++ allow taking the address of an incomplete reference type?
Couldn't it be potentially illegal, as shown above? Is this intentional?
Yes, that's intentional, and the possibility of breakage if
operator&
is overloaded is known.Taking the address of incomplete types has been possible since long before C++. In C, there is absolutely no risk of any breakage, because
&
cannot be overloaded.C++ chose not to unnecessarily break previously valid programs, and simply specified that if an incomplete type does turn out to have an overloaded
&
operator, it's unspecified whether the overloaded operator gets used.Quoting N4140:
This can be interpreted to apply even to a class currently being declared, and even when a declaration of
operator&
has already been seen:Here, GCC gives
m
typeA *
and rejects the program, but clang gives it typeint
and accepts it.