I have a little synthetic example that have behaviour I want to change, but don't quite know how.
What I have is this:
Common header statich.h that have external declaration of some variable:
#include <iostream>
struct S {
S() : x(42) {
std::cout << "S(), this=" << this << std::endl;
}
~S() {
std::cout << "~S(), this=" << this << std::endl;
}
int x;
};
extern S nakedS;
Static library libstatic.a compiled from source file statich.cpp, that have definition of that external variable:
#include "statich.h"
S nakedS;
Dynamic library libdyn.so compiled from source file dyn.cpp and linking with libstatic.a. Here's source code:
#include "statich.h"
void foo() {
std::cout << "I'm foo() from dyn! nakedS.x == " << nakedS.x << std::endl;
}
Executable supertest that compiled from source file main.cpp and linking with both of libraries, static and shared. Here's source code:
#include "statich.h"
int main() {
std::cout << "nakedS.x == " << nakedS.x << std::endl;
}
I have CMakeLists.txt file that build all that stuff for me. Here it is:
cmake_minimum_required(VERSION 2.8.12)
set(CMAKE_CXX_FLAGS
"${CMAKE_CXX_FLAGS} -fPIC"
)
add_library( static STATIC "statich.cpp" )
add_library( dyn SHARED "dyn.cpp" )
target_link_libraries( dyn static )
add_executable( supertest main.cpp )
set(DEPS
static
dyn
)
target_link_libraries( supertest ${DEPS} )
Point is, when I run cmake . && make && ./supertest
I got this output:
S(), this=0x6012c4
S(), this=0x6012c4
nakedS.x == 42
~S(), this=0x6012c4
~S(), this=0x6012c4
Which means double initialization of same object, that is not what I want at all. Can I change this behaviour without replacing libdyn.so with static analogue? Maybe, some compiler/linker flags? What should I read to learn more about it? Any help would be appreciated.
Also, I got this behaviour on my specific compiler version: gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC)
On other machine where I have diffirent compiler: gcc version 4.6.4 (Ubuntu/Linaro 4.6.4-1ubuntu1~12.04) All works fine.
Thanks in advance!
This is expected behaviour. To work it around, you could define your variable as weak, e.g.
#include "statich.h"
__attribute__((weak)) S nakedS;