Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ static member initialization confuses with compiler linking. How to solve?

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.

like image 369
transang Avatar asked Dec 05 '22 15:12

transang


1 Answers

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.

like image 195
Rob Kennedy Avatar answered Dec 09 '22 14:12

Rob Kennedy