【发布时间】:2015-12-25 02:03:09
【问题描述】:
staticconst 成员的类内初始化让我有点困惑。例如,在下面的代码中:
#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) 在链接时失败,确实如此。但是,每当我使用诸如-O1/2/3 之类的优化标志时,以下行std::cout << g(Foo::n) << std::endl; 只能通过gcc 编译和链接(clang 仍然会发出链接器错误)。
- 为什么 gcc(用 gcc5.2.0 和 gcc 4.9.3 尝试过)在优化开启时编译并链接代码?
- 我是否正确地说类内静态 const 成员的唯一用途是在常量表达式中,例如
h<Foo::n>调用中的模板参数,在这种情况下代码应该链接?
【问题讨论】:
-
这是一个专门的 C++11 问题吗? odr 引用 change a bit between C++11 and C++14 虽然我认为在这种情况下并不重要,但在某些情况下确实如此。
-
@ShafikYaghmour 我使用
-std=c++11编译,但问题本身不一定仅限于 C++11(或 C++14)。 O 也观察到与-std=c++98相同的行为。
标签: c++ gcc linker one-definition-rule