Question

I have trouble with these static members initialization of c++ classes. See my code for more info.

Source

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

staff.cpp

#include "header.h"
string Staff::str = "(staff)";

boss.cpp

#include "header.h"
string Boss::str = "I call " + Staff::str;

main.cpp

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

And here are many compile codes with different results:

Pre-compile:

g++ -c boss.cpp
g++ -c staff.cpp
ar rcs lib.a boss.o staff.o
ar rcs rlib.a staff.o boss.o

Compile, run and result:

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)

I want to use library archive instead of confusing with giant objects order when compiling. Help me to solve them.

Thank you.

Was it helpful?

Solution

The initialization order of static variables in separate translation units is undefined. Your two source files make up two separate translation units, and each one defines one variable. The segmentation fault probably occurs while attempting to use Staff::str to initialize Boss::str when Staff::str hasn't been initialized yet.

To solve it, define them both in the same single translation unit:

#include "header.h"
string Staff::str = "(staff)";
string Boss::str = "I call " + Staff::str;

Or make their initializations independent of each other:

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

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

string Boss::str = "I call " + Staff::get_str();

From your first two examples, it appears that the initialization order is related to the linking order, but you mustn't rely on that.

OTHER TIPS

Initialization order of global variables in separate translation units is undefined. You can wrap them in a function to make it work:

class Staff{ public: static & string str();};
class Boss{ public: static & string str();};

string & Staff::str()
{
  static string s = "(staff)";
  return s;
}

string & Boss::str()
{
  static string s = "I call " + Staff::str();
  return s;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top