您的代码不是真正的 C++。它使用复合文字,这是 C99 功能。在 C99 中,它计算为一个左值,并且在那里获取文字的地址是完全可以的。将这个扩展集成到 C++ 中,GCC 似乎改变了它的规则并使其成为一个右值,更好地将它们的分类符合 C++ 的现有规则,用于也产生右值的通常强制转换。
GCC不喜欢&(Temp){42}
,抱怨我拿了一个临时的地址。这是一个关于它仍然接受但并不真正喜欢的无效代码的警告。对于其他明显错误的代码,例如 ,也给出了相同的警告&A()
,这是一种合法的函数式 C++ 强制转换,它也会产生一个右值,因此不能用作地址运算符的操作数。
GCC 将复合文字集成到 C++ 中也过早地破坏了临时性,如下面的测试所示
#include <iostream>
struct B {
~B() {
std::cout << "~B" << std::endl;
}
};
struct A { int i; B b; };
int main() {
A *a = &(A){0};
std::cout << "main" << std::endl;
}
在 C99 中,字面量所指的对象将在整个块中处于活动状态(它将具有自动存储持续时间)。在 GNU C++ 中,对象已经在完整表达式的末尾被破坏,甚至在到达其块的末尾之前(“~B”在“main”之前打印)。