静态字段初始化顺序

时间:2014-05-24 02:07:53

标签: c++ windows visual-c++

静态常量字段初始化顺序中是否有陷阱?

template <typename T>
struct constant_test {

    static const T PI;
    static const T FULL_CIRCLE;
    static const T HALF_CIRCLE;
    static const T DEG_TO_RAD;

};

template <typename T> const T constant_test<T>::PI = 3.141592653589f;
template <typename T> const T constant_test<T>::FULL_CIRCLE = 360.0f;
template <typename T> const T constant_test<T>::HALF_CIRCLE = constant_test<T>::FULL_CIRCLE / 2;
template <typename T> const T constant_test<T>::DEG_TO_RAD = constant_test<T>::PI / constant_test<T>::HALF_CIRCLE;

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
    // uncomment to make it work
    // float test_ref = constant_test<float>::HALF_CIRCLE;
    char buf[128];
    sprintf_s(buf, 128, "Value: %f", constant_test<float>::DEG_TO_RAD);
    OutputDebugStringA(buf); // prints "Value: 1.#INF00"
    return 0;
}

表达式constant_test<float>::DEG_TO_RAD神奇地返回-Infinity

如果我删除模板参数并使它们只浮动,则正确评估常量(0.017453)

如果我添加对HALF_CIRCLE常量的引用,那么它也会被正确评估

我正在使用MSVC 2013 SP 1。

为什么呢? 我错过了什么?

1 个答案:

答案 0 :(得分:1)

此代码打印出正确的值(g ++ 4.8.2,OS X):

#include <iostream>

using namespace std;

template <typename T>
struct constant_test {

    static const T PI;
    static const T FULL_CIRCLE;
    static const T HALF_CIRCLE;
    static const T DEG_TO_RAD;

};

template <typename T> const T constant_test<T>::PI = 3.141592653589f;
template <typename T> const T constant_test<T>::FULL_CIRCLE = 360.0f;
template <typename T> const T constant_test<T>::HALF_CIRCLE = constant_test<T>::FULL_CIRCLE / 2;
template <typename T> const T constant_test<T>::DEG_TO_RAD = constant_test<T>::PI / constant_test<T>::HALF_CIRCLE;

int main()
{
    // uncomment to make it work
    //float test_ref = constant_test<float>::HALF_CIRCLE;
    cout << "Value: " << constant_test<float>::DEG_TO_RAD << endl; // correct result

    char buf[128];
    sprintf(buf, "Value: %f", constant_test<float>::DEG_TO_RAD );
    cout << buf << endl; // again correct

    return 0;
}

输出:

Value: 0.0174533
Value: 0.017453

静态常量按顺序初始化,请参阅https://stackoverflow.com/a/10011133/3093378,因此在显示时应该初始化constant_test<T>::DEG_TO_RAD(从上面的代码看起来是这样)。