我对 static
有点困惑const
的类内初始化成员。例如,在下面的代码中:
#include <iostream>
struct Foo
{
const static int n = 42;
};
// const int Foo::n; // No ODR
void f(const int& param)
{
std::cout << param << std::endl;
}
int g(const int& param)
{
return param;
}
template<int N>
void h()
{
std::cout << N << std::endl;
}
int main()
{
// f(Foo::n); // linker error, both g++/clang++
std::cout << g(Foo::n) << std::endl; // OK in g++ only with -O(1,2 or 3) flag, why?!
h<Foo::n>(); // this should be fine
}
我没有定义 Foo::n
(该行已注释)。所以,我期待电话 f(Foo::n)
在链接时失败,确实如此。但是,以下行 std::cout << g(Foo::n) << std::endl;
每当我使用诸如 -O1/2/3
之类的优化标志时,只能通过 gcc 编译和链接(clang 仍然会发出链接器错误) .
- 为什么打开优化后 gcc(尝试使用 gcc5.2.0 和 gcc 4.9.3)编译并链接代码?
- 我说类内静态常量成员的唯一用法是在常量表达式中,例如
h<Foo::n>
中的模板参数是否正确?调用,在这种情况下代码应该链接?
最佳答案
我假设编译器在优化期间执行以下操作:
值
const static int n
在任何地方都是内联的。没有为变量n
分配内存,对它的引用变得无效。函数f()
需要对n
的引用,因此程序不会被编译。g
函数简短。它被有效地内联和优化。优化后,函数g
不需要引用n
,它只返回常量值42。
解决方法是在类外定义变量:
struct Foo
{
const static int n;
};
const int Foo::n = 42;
关于c++ - 在类静态常量 ODR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32812663/