I am curious about whether static variables instantiated inside shared libraries are instantiated at all. First of all, here is the code:
AClass.h
class A {
public:
A(int x) { cout << "A constructor called." << endl; }
};
MyLib.cpp
#include "AClass.h"
static A StaticVariableA(50);
So, with this code plus a Main.cpp file (with nothing but a empty main function), I wanted to get the constructor to be called by the initialization of the variable inside MyLib.cpp.
I compiled MyLib.cpp to a shared library, and linked the main program to it in many ways without success. Given that the two files are already compiled to an object file:
(first compiled MyLib.cpp to a shared library)
$ g++ -O0 -fPIC -shared -Wl,-soname,libMyLib.so -o libMyLib.so MyLib.o
(Tried to link the two files)
$ g++ -O0 Main.o -rdynamic libMyLib.so -Wl,-rpath,./
$ g++ -O0 Main.o -L . -Wl,-rpath,./ -lMyLib
No success until now, I ask you: is this possible? If it is not possible, why? How do static variables are handled in a shared library? (I am mainly interested in Linux machines)
(I know that I am not supposed to use shared libraries like this. But I just want to know what it does that this doesn't work)
Strangely enough, this code works. When linking the library GMLOSStFeatEx, which is a shared library compiled with /src/FeatureExtractor/
files, to the /tools/Dummy.cpp
. It calls the constructor of static variables of type RegisterStaticFeature
.
EDIT
It seems like @Pupsik said, it is being optimized out. However, the code I linked above does not get optimized out. It also doesn't have any functions that are called or referenced by outside code.
In this question it suggests the use of the linker flag -no-as-needed
, which works. But as it is possible to see below, there is no such flag when compiling the code I mentioned.
/usr/bin/c++ -O0 -g -I/usr/local/include -fPIC -fvisibility-inlines-hidden
-Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual
-Wno-missing-field-initializers -pedantic -Wno-long-long
-Wno-maybe-uninitialized -Wnon-virtual-dtor -Wno-comment -std=c++11 -g
-fno-exceptions -fno-rtti -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS
-D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -L/usr/local/lib
CMakeFiles/Dummy.dir/DummyMain.cpp.o -o Dummy -rdynamic ../src
/FeatureExtractor/libGMLOSStFeatEx.so ../src/FeatureExtractor
/libGMLOSDynFeatEx.so ../src/Support/libGMLOSCfgPrinter.so
-lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMX86Desc -lLLVMX86Info
-lLLVMMCDisassembler -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMCodeGen
-lLLVMScalarOpts -lLLVMProfileData -lLLVMInstCombine -lLLVMInstrumentation
-lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMIRReader -lLLVMAsmParser
-lLLVMTransformUtils -lLLVMipa -lLLVMMCJIT -lLLVMExecutionEngine -lLLVMTarget
-lLLVMAnalysis -lLLVMRuntimeDyld -lLLVMObject -lLLVMMCParser -lLLVMBitReader
-lLLVMMC -lLLVMCore -lLLVMSupport -lpapi -lrt -ldl -ltinfo -lpthread -lz -lm
-Wl,-rpath,/path-to-gmlos/build/src/FeatureExtractor:/path-to-gmlos/build/src/Support