发生段故障取决于gcc编译命令中的cpp序列?

Gst*_*tso 2 c++ gcc segmentation-fault

我编写了一个简单的程序,当定义了一个新类(例如:One,Two)时,它会将值添加到全局集合容器中:

GlobalSet.h

#include <set>
struct GlobalSet{
public:
    static void* addValue(int val);
private:
    static std::set<int> s;
};
Run Code Online (Sandbox Code Playgroud)

GlobalSet.cpp

#include "GlobalSet.cpp"
std::set<int> GlobalSet::s;
void* GlobalSet::addValue(int val){
    s.insert(val);
    return NULL;
}
Run Code Online (Sandbox Code Playgroud)

One.h

struct One{};
Run Code Online (Sandbox Code Playgroud)

One.cpp

#include "One.h"
#include "GlobalSet.h"
void* globalset =GlobalSet::addValue(1);
Run Code Online (Sandbox Code Playgroud)

Two.h

struct Two{};
Run Code Online (Sandbox Code Playgroud)

Two.cpp

#include "Two.h"
#include "GlobalSet.h"
void* globalset2 =GlobalSet::addValue(2);
Run Code Online (Sandbox Code Playgroud)

TEST.CPP

int main(){
return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是这个程序会导致段错误依赖于gcc编译命令中的cpp序列:

g++ GlobalSet.cpp One.cpp Two.cpp test.cpp -o test.exe //normal
g++ One.cpp Two.cpp GlobalSet.cpp test.cpp -o test.exe //segment fault!!
Run Code Online (Sandbox Code Playgroud)

为什么会这样?如何解决问题,使其无需关心gcc编译中的cpp序列?

Sam*_*hik 6

欢迎使用静态初始化订单Fiasco.

C++标准不保证多个转换单元中全局对象的初始化顺序.

根据您的链接顺序,您的代码将globalset2首先尝试构建.但是,这会调用静态类方法addValue(),该方法尝试访问std::set尚未构造的方法.

未定义的行为和崩溃.

要解决此问题,请访问www.google.com,搜索"静态初始化顺序惨败",并继续阅读,直到您了解问题为止.完成后,您将在代码中知道如何修复它.