Why are we allowed to take the address of an incomplete type?

这一生的挚爱 提交于 2019-12-22 04:04:30

问题


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?


回答1:


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:

5.3.1 Unary operators [expr.unary.op]

If & is applied to an lvalue of incomplete class type and the complete type declares operator&(), it is unspecified whether the operator has the built-in meaning or the operator function is called.

This can be interpreted to apply even to a class currently being declared, and even when a declaration of operator& has already been seen:

extern struct A a;
struct A {
  int operator&();
  decltype(&a) m; // int, or A *?
};
int main() {
  return A().m; // only valid if m is int
}

Here, GCC gives m type A * and rejects the program, but clang gives it type int and accepts it.



来源:https://stackoverflow.com/questions/29181013/why-are-we-allowed-to-take-the-address-of-an-incomplete-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!