Ответ 1
Да, это преднамеренное и возможность поломки, если operator&
перегружена, известно.
Возникновение адреса неполных типов возможно задолго до С++. В C нет абсолютно никакого риска поломки, потому что &
не может быть перегружен.
С++ решила не излишне разорвать ранее действующие программы и просто указала, что если у неполного типа оказывается перегруженный оператор &
, он не укажет, будет ли использоваться перегруженный оператор.
Цитата N4140:
5.3.1 Унарные операторы [expr.unary.op]
Если
&
применяется к lvalue неполного типа класса и полный тип объявляет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
и принимает его.