为什么我们允许使用不完整类型的地址? [英] Why are we allowed to take the address of an incomplete type?
问题描述
请考虑这个代码:
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
为什么C ++允许使用不完整引用类型的地址?
难道不可能是非法的,如上所示?这是有意的吗?
是的,这是故意的,如果 operator& code>是重载的。
从C ++开始,就可以获取不完整类型的地址。在C中,绝对没有任何破损的风险,因为&
不能重载。
C ++选择不不必要地破坏以前有效的程序,并简单地指定如果一个不完整的类型确实有一个重载的&
运算符,它是未指定重载的运算符是否被使用。 p>
引用N4140:
5.3.1一元运算符[expr.unary .op]
如果
&
应用于不完整类类型的左值,类型声明operator&()
,未指定操作符是否具有内置含义或调用操作符函数。
这可以被解释为甚至应用于当前被声明的类,即使当 operator&
的声明已经见:
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
}
这里,GCC给出 m 键入
A *
并拒绝程序,但clang给它类型 int
并接受它。
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:
5.3.1 Unary operators [expr.unary.op]
If
&
is applied to an lvalue of incomplete class type and the complete type declaresoperator&()
, 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.
这篇关于为什么我们允许使用不完整类型的地址?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!