获取静态成员C+的地址+;常见问题 < C++ FAQ试图传达什么?
如果(且仅当)静态成员具有类外定义,则可以获取其地址:获取静态成员C+的地址+;常见问题 < C++ FAQ试图传达什么?,c++,C++,如果(且仅当)静态成员具有类外定义,则可以获取其地址: 但是,您可以使用-O2进行编译。编译器可以优化掉常量int*p1=&AE::c6赋值(因为它没有效果),因此在最终代码中不需要地址AE::c6,这就是它编译的原因 它给出了一个链接器错误,没有进行优化 如果您开始使用p1(例如std::cout常见问题解答中的注释具有误导性;AE::c6和 AE::c7是左值。如果没有对AE::c7的定义, 相关代码违反了“一个定义”规则: 表达式可能会被计算,除非它是 未赋值的操作数或其子表达式。变量 其
但是,您可以使用
-O2进行编译。编译器可以优化掉常量int*p1=&AE::c6代码>赋值(因为它没有效果),因此在最终代码中不需要地址AE::c6
,这就是它编译的原因
它给出了一个链接器错误,没有进行优化
如果您开始使用p1
(例如std::cout常见问题解答中的注释具有误导性;AE::c6
和
AE::c7
是左值。如果没有对AE::c7
的定义,
相关代码违反了“一个定义”规则:
表达式可能会被计算,除非它是
未赋值的操作数或其子表达式。变量
其名称显示为可能计算的表达式是
除非是满足要求的对象,否则使用odr
用于出现在常量表达式中,并将左值转换为右值
立即应用转换。[…]
[……]
每个程序应包含每个程序的一个定义
odr在其中使用的非内联函数或变量
编程;无需诊断
实际上,链接器通常会在以下情况下生成错误:
编译器实际上需要对象的地址
在这种情况下,如果以后不使用p2
,则编译器将不需要
地址,因为优化将删除p1
的定义。
发生这种情况的更常见的情况是
以下:
std::vector<int> v;
v.push_back( AE::c6 );
std::vector v;
v、 推回(AE::c6);
由于std::vector::push_back
接受一个引用,因此没有
立即将左值转换为右值,定义为
必需。实际上,std::vector::push_back
是一个模板
函数(通常是内联函数),因此编译器可以查看其
实现,并将值向下传播到函数中
到左值到右值转换实际发生的位置
发生,代码将编译并工作。但它仍然是
形式上未定义的行为。如果分别编译类AE
和f()
,然后链接对象,会发生什么情况?@juanchopanza它使用-O2
和f()编译
本质上是一个nop。然而,它给出了一个链接器错误,-O0
,就像原始程序对-O0
@Csq所做的那样。是的,我看到并投票了你的答案。或者,std::cout这里有一个相关链接,最初在我对删除答案的评论中:这可能也有关联:好的,我会说同样的话这里也是(正如我在一个已删除的答案中所说的),FAQ IMO中的注释//error:c6不是左值
具有误导性,乍一看这似乎是一个语法错误。链接器错误是显而易见的,但优化后我却意外地不知道
std::vector<int> v;
v.push_back( AE::c6 );