gpt4 book ai didi

c++ - 静态/动态链接的静态初始化顺序问题

转载 作者:行者123 更新时间:2023-12-01 14:57:59 30 4
gpt4 key购买 nike

如果c++应用程序是按以下方式组织的

//file1.cpp
static Y sgObj = X::getInitObject(0); //declared in file scope

//file2.cpp
namespace{
int getInitValue()
{
static int val = Y::sObj.initVal();
return val;
}
}

namespace X{
Y getInitObject(int initVal)
{
if(initVal < getInitValue())
{
cout << "Print some log message" << endl;
}

return Y::initMethod(initVal);
}
}

//file.h
//This class is shipped as static and dynamic library, and application is supposed to link
//them in their executable based on their need
class Y{
public:
int initVal();
static Y initMethod(int val);
static Y sObj;
};

假设包括了所有必需的头文件,并且我们能够为该应用程序创建可执行文件,那么在以下情况下,我在file1.cpp中创建对象的方式是否存在初始化问题:
  • 静态
    vs
  • 动态链接到库(对应于类Y的实现)以创建对象sgObj。

  • 鉴于类Y的实现未公开给应用程序,我们无法更改其静态成员sObj的创建方式。

    它与所使用的平台/编译器有关系吗?

    最佳答案

    您必须确保在定义file1.cpp之前<iostream>包括sgObj,或者您需要在静态初始化期间使用std::ios_base::Init之前构造一个cout类型的本地对象:

      if(initVal < getInitValue())
    {
    (void)std::ios_base::Init{};
    cout << "Print some log message" << endl;
    }

    否则,到达该行时 cout可能不会初始化。

    除此之外,假设 Y::sObj在未显示的另一个翻译单元中定义,则 sgObj和全局 Y::sObj的构建顺序不确定,因为在不同翻译单元之间进行动态初始化的顺序不确定。

    因此,如果从 Y::initMethod的全局初始化调用的 sgObj访问 Y::sObj,则它可能尚未初始化,从而导致未定义的行为。

    如果希望在其他非局部静态变量的静态初始化期间使用静态 Y::sObj,则需要使用类似Meyers单例模式的方法:
    class Y{
    //...
    static Y& sObj {
    static Y instance /* initializer here */;
    return instance;
    }
    };

    用作 Y::sObj()而不是 Y::sObj

    关于c++ - 静态/动态链接的静态初始化顺序问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60475648/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com