C++静态成员初始化与编译器链接混淆.怎么解决?

tra*_*ang 2 c++ static-variables static-libraries segmentation-fault static-initialization

我在使用这些静态成员初始化c ++类时遇到了麻烦.有关详细信息,请参阅我的代码

资源

header.h

#ifndef HEADER_H
#define HEADER_H
#include <string>
using namespace std;
class Staff{ public: static string str;};
class Boss{ public: static string str;};
#endif
Run Code Online (Sandbox Code Playgroud)

staff.cpp

#include "header.h"
string Staff::str = "(staff)";
Run Code Online (Sandbox Code Playgroud)

boss.cpp

#include "header.h"
string Boss::str = "I call " + Staff::str;
Run Code Online (Sandbox Code Playgroud)

main.cpp中

#include <iostream>
#include "header.h"
int main(){cout << Boss::str << endl;}
Run Code Online (Sandbox Code Playgroud)

这里有许多编译代码,结果不同:

预编译:

g++ -c boss.cpp
g++ -c staff.cpp
ar rcs lib.a boss.o staff.o
ar rcs rlib.a staff.o boss.o
Run Code Online (Sandbox Code Playgroud)

编译,运行和结果:

g++ main.cpp staff.cpp boss.cpp ; ./a.out
==> I call (staff)
g++ main.cpp boss.cpp staff.cpp ; ./a.out
==> segmentation fault (core dumped)
g++ main.cpp lib.a ; ./a.out
==> segmentation fault (core dumped)
g++ main.cpp rlib.a ; ./a.out
==>segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)

我想在编译时使用库存档而不是与巨型对象混淆.帮我解决一下

谢谢.

Rob*_*edy 10

单独的转换单元中的静态变量的初始化顺序是未定义的.您的两个源文件组成两个单独的转换单元,每个转换单元定义一个变量.在尝试使用尚未Staff::str初始化Boss::str时初始化时,可能会发生分段错误Staff::str.

要解决它,请在同一个翻译单元中定义它们:

#include "header.h"
string Staff::str = "(staff)";
string Boss::str = "I call " + Staff::str;
Run Code Online (Sandbox Code Playgroud)

或者使它们的初始化彼此独立:

std::string Staff::get_str() {
  return "(staff)";
}

string Staff::str = Staff::get_str(); 

string Boss::str = "I call " + Staff::get_str();
Run Code Online (Sandbox Code Playgroud)

从前两个示例中可以看出,初始化顺序与链接顺序有关,但您不能依赖它.