Static linking of C++ code - c++

I have the following problem: I use some classes like the following to initialize C libraries:
class Hello
{
public:
Hello()
{
cout << "Hello world" << endl;
}
~Hello()
{
cout << "Goodbye cruel world" << endl;
}
} hello_inst;
If I include this code in a hello.cc file and compile it together with another file containing my main(), then the hello_inst is created before and destroyed after the call
to main(). In this case it just prints some lines, in my project I initialize libxml via
LIBXML_TEST_VERSION.
I am creating multiple executables which share a lot of the same code in a cmake project.
According to this thread: Adding multiple executables in CMake I created a static library containing the code shown above and then linked the executables against that library. Unfortunately in that case the hello_inst is never created (and libxml2 is never initialized). How can I fix this problem?

I had a similar problem and solved it by defining my libraries as static. Therefore I used the following code:
add_library( MyLib SHARED ${LBMLIB_SRCS} ${LBMLIB_HEADER})
Maybe this fixes your problem

There is no official way of forcing shared libraries global variables to be initialised by the standard and is compiler dependent.
Usually this is done either the first time something in that library is actually used (A class, function, or variable) or when the variable itself is actually used.
If you want to force hello_inst to be used, call a function on it, then see if and when the constructor and destructors are called.
Read this thread for more information:
http://www.gamedev.net/topic/622861-how-to-force-global-variable-which-define-in-a-static-library-to-initialize/

As far as I'm aware, statics defined in library should be constructed before main is called and destroyed after main, in the manner you describe. Indeed I have used shared libraries in many projects, and have never encountered the problems you describe.
I understand a library file, to be little more than a container of object files.
However, that said.....
If your code does nothing with the object that is created, the linker is free to remove it (dead code removal). I would suggest making sure the static object is referenced. Call a member function, perhaps?

Related

What does bazel alwayslink = true mean?

I'm new to bazel. Here's the explanation in bazel doc:
https://docs.bazel.build/versions/master/be/c-cpp.html#cc_library.alwayslink
alwayslink
Boolean; optional; nonconfigurable; default is 0
If 1, any binary that depends (directly or indirectly) on this C++
library will link in all the object files for the files listed in
srcs, even if some contain no symbols referenced by the binary. This
is useful if your code isn't explicitly called by code in the binary,
e.g., if your code registers to receive some callback provided by some
service.
I don't quite understand the last sentence: e.g., if your code registers to receive some callback provided by some service. Can anyone give and example? Thanks!
e.g., if your code registers to receive some callback provided by some service.
AIUI, this is the case when the cc_binary builds a shared library / a DLL. You need the linker to keep all symbols, even if unused, because another binary who loads the .so/.dll at runtime might need those symbols.
Most linkers will remove object files if they are unreferenced by the rest of the program, even if they contain dynamic initialization.
For example:
struct S { S(); }
S s;
S::S() {
std::cout << "Hello, World!";
}
This code prints Hello, World! during dynamic initialization. The constructor of the global variable s prints it, and that is called during dynamic initialization.
If you link this code with a program, it might be removed, so Hello, World! will not be printed by the program.
The alwayslink flag prevents this, and forces the program to include the dynamic initialization.
The usual use case for this is when the dynamic initialization causes registration of stuff. For example it might be a "plugin" for some application, and its dynamic initialization adds it to the global list of plugins.
It has nothing to do with shared vs static libraries.

I can not get an execute-on-load function to work in a library using Qt

I have several libraries, each of which implement a class (derived from QObject). I would like each of these libraries to execute a function the first time they load. I found a couple of similar questions here:
Automatically executed functions when loading shared libraries
and
How exactly does __attribute__((constructor)) work?
but any initialization function I create based on the answers never executes. I've tried creating the function in a namespace, outside a namespace (and not a part of my class), using __attribute__((constructor)), naming it _init, and specifying the function name to the linker with:
QMAKE_LFLAGS_RELEASE += -Wl,-init,libinitfunc
None of these have worked.
I should also note that I'm cross-compiling these libraries to run on an embedded ARM device that uses busybox for much of its functionality.
Since this is C++ code, you shouldn't need C-style hacks.
class LibInstance {
public:
LibInstance() {
qDebug() << __FILE__ << "has been initialized";
}
~LibInstance() {
qDebug() << __FILE__ << "has been unloaded";
}
}
Q_GLOBAL_STATIC(LibInstance, libInstance)
class LibExecutor {
LibExecutor() { libInstance(); }
};
static LibExecutor libExecutor;
An instance of LibExecutor is guaranteed to be constructed, in a non-threadsafe way, before main() starts running; or before the library finishes loading, if it's demand-loaded. The LibExecutor's constructor is then using the Q_GLOBAL_STATIC implementation to thread-safely execute the LibInstance's constructor.
It is in LibInstance's constructor that you place the initialization functionality you desire. The destructor will be called when the library is being unloaded.
It is generally safe, cross platform, and used within Qt itself.

Template class specialized inside and outside lib

Consider this synthetic example. I have two native C++ projects in my Visual Studio 2010 solution. One is console exe and another is lib.
There are two files in lib:
// TImage.h
template<class T> class TImage
{
public:
TImage()
{
#ifndef _LIB
std::cout << "Created (main), ";
#else
std::cout << "Created (lib), ";
#endif
std::cout << sizeof(TImage<T>) << std::endl;
}
#ifdef _LIB
T c[10];
#endif
};
void CreateImageChar();
void CreateImageInt();
and
// TImage.cpp
void CreateImageChar()
{
TImage<char> image;
std::cout << sizeof(TImage<char>) << std::endl;
}
void CreateImageInt()
{
TImage<int> image;
std::cout << sizeof(TImage<int>) << std::endl;
}
And one file in exe:
// main.cpp
int _tmain(int argc, _TCHAR* argv[])
{
TImage<char> image;
std::cout << sizeof(TImage<char>) << std::endl;
CreateImageChar();
CreateImageInt();
return 0;
}
I know, I shouldn't actually do like this, but this is just for understanding what is happening. And that's, what happens:
// cout:
Created (main), 1
1
Created (main), 1
10
Created (lib), 40
40
So how exactly this happened, that linker overrides lib's version of TImage<char> with exe's version of TImage<char>? But since there is no exe's version of TImage<int>, it preserves lib's version of TImage<int>?.. Is this behavior standardized, and if so, where can I found the description?
Update: Explanations of the effect given below are correct, thanks. But the question was "how exactly this happened"?.. I expected to get some linker error like "multiply defined symbols". So the most suitable answer is from Antonio PĂ©rez's reply.
Template code creates duplicated object code.
The compiler copies the template code for the type you provide when you instance the template. So when TImage.cpp is compiled you get object code for two versions of your template, one for char and one for int in TImage.o. Then main.cpp is compiled and you get a new version of your template for char in main.o. Then the linker happens to use the one in main.o always.
This explains why your output yields the 'Created' lines. But it was a little bit puzzling to see the mismatch in lines 3, 4 regarding object's size:
Created (main), 1
10
This is due to the compiler resolving the sizeof operator during compile-time.
I am assuming here that you are building a static library, because you do not have any __decelspec(dllexport) or extern "C" in the code. What happens here is the following. The compiler create an instance of TImage<char> and TImage<int> for your lib. It also creates an instance for the your executable. When the linker joins the static library and the objects of the executable together duplicate code gets removed. Note here that static libraries are linked in like object code, so it does not make any difference if you create one big executable or multiple static libraries and an executable. If you would build one executable the result would be dependent on the order the objects are linked in; aka "not defined".
If you change the library to a DLL the behavior changes. Since you are calling over the boundary of a DLL, each needs their copy of TImage<char>. In most cases DLLs behave more as you would expect a library to work. Static libraries are normally just a convenience, so you need not put the code into your project.
Note: This only applies on Windows. On POSIX systems *.a files behave like *.so file, which creates quite some head aches for compiler developers.
Edit: Just never ever pass the TImage class over a DLL boundary. That will ensure a crash. That is the same reason why Microsoft's std::string implementation crashes when mixing debug and release builds. They do exactly what you did only with the NDEBUG macro.
The compiler will always instantiate your template when you use it - if the definition is available.
This means, it generates the required functions, methods etc. for the desired specialization and places them in the object file. This is the reason why you either need to have the definition available (usually in a header file) or an existing instantiation (e.g. in another object file or library) for the specific specialization that you are using.
Now, when linking, a situation might occur which is usually not allowed: more than one definition per class/function/method. For templates, this is specifically allowed and the compiler will choose one definition for you. That is what is happening in your case and what you call "overriding".
Memory layout is a compile-time concept; it has nothing to do with the linker. The main function thinks TImage is smaller than the CreateImage... functions do, because it was compiled with a different version of TImage.
If the CreateImage... function were defined in the header as inline functions, they would become part of main.cpp's compilation unit, and would thus report the same size characteristics as main reports.
This also has nothing to do with templates and when they get instantiated. You'd observe the same behaviour if TImage was an ordinary class.
EDIT: I just noticed that third line of cout doesn't contain "Created (lib), 10". Assuming it's not a typo, I suspect what's happening is that CreateImageChar is not inlining the call to the constructor, and is thus using main.cpp's version.
Template creates duplicates of classes (ie space) during the compilation itself. So when you are using too much of templates, the smart compilers try to optimize them based on parametrization of templates.
Within your library, you have a TImage that prints "lib" on construction, and contains an array of T. There are two of these, one for int and one for char.
In main, you have a TImage that prints "main" on construction, and does not contain an array of T. There is only the char version in this case; because you never ask for the int version to be created.
When you go to link, the linker choses one of the two TImage<char> constructors as the official one; it happens to chose main's version. This is why your third line prints "main" instead of "lib"; because you are calling that version of the constructor. Generally, you don't care which version of the constructor gets called... they are required to all be the same, but you have violated that requirement.
That's the important part: your code is now broken. Within your library functions, you expect to see that array of char within TImage<char> but the constructor never creates it. Further, imagine if you say new TImage<char> within main, and pass the pointer to a function within your library, where it gets deleted. main allocates one byte of space, the library function tries to release ten. Or if your CreateImageChar method returned the TImage<char> it creates... main will allocate one byte on the stack for the return value, and CreateImageChar will fill it with ten bytes of data. And so on.

How do I make an unreferenced object load in C++?

I have a .cpp file (let's call it statinit.cpp) compiled and linked into my executable using gcc.
My main() function is not in statinit.cpp.
statinit.cpp has some static initializations that I need running.
However, I never explicitly reference anything from statinit.cpp in my main(), or in anything referenced by it.
What happens (I suppose) is that the linked object created from statinit.cpp is never loaded on runtime, so my static initializations are never run, causing a problem elsewhere in the code (that was very difficult to debug, but I traced it eventually).
Is there a standard library function, linker option, compiler option, or something that can let me force that object to load on runtime without referencing one of its elements?
What I thought to do is to define a dummy function in statinit.cpp, declare it in a header file that main() sees, and call that dummy function from main(). However, this is a very ugly solution and I'd very much like to avoid making changes in statinit.cpp itself.
Thanks,
Daniel
It is not exactly clear what the problem is:
C++ does not have the concept of static initializers.
So one presume you have an object in "File Scope".
If this object is in the global namespace then it will be constructed before main() is called and destroyed after main() exits (assuming it is in the application).
If this object is in a namespace then optionally the implementation can opt to lazy initialize the variable. This just means that it will be fully initialized before first use. So if you are relying on a side affect from construction then put the object in the global namespace.
Now a reason you may not be seeing the constructor to this object execute is that it was not linked into the application. This is a linker issue and not a language issue. This happens when the object is compiled into a static library and your application is then linked against the static library. The linker will only load into the application functions/objects that are explicitly referenced from the application (ie things that resolve undefined things in the symbol table).
To solve this problem you have a couple of options.
Don't use static libraries.
Compile into dynamic libraries (the norm nowadays).
Compile all the source directly into the application.
Make an explicit reference to the object from within main.
I ran into the same problem.
Write a file, DoNotOptimizeAway.cpp:
void NoDeadcodeElimination()
{
// Here use at least once each of the variables that you'll need.
}
Then call NoDeadcodeElimination() from main.
EDIT: alternatively you can edit your linker options and tell it to always link everything, even if it's not used. I don't like this approach though since executables will get much bigger.
These problems, and the problems with these potential solutions all revolve around the fact that you can't guarantee much about static initialization. So since it's not dependable, don't depend on it!
Explicitly initialize data with a static "InititalizeLibrary" type static function. Now you guarantee it happens, and you guarantee when it happens in relation to other code based on when you make the call.
One C++'ish way to do this is with Singletons.
Essentially, write a function to return a reference to the object. To force it to initialize, make it a static object inside the function.
Make a class static function that is vaguely like this:
class MyClass {
static MyClass& getObject()
{
static MyObject obj;
return obj;
}
};
Since you are using C++, you could always declare a global object (ie a global variable that references a class in statinit.cpp. As always, the constructor will be called on initialization and since the object is global, this will be called before main() is run.
There is one very important caveat though. There is no guarantee as to when the constructor will be called and there is no way to explicitly order when each of these constructors is called. This will also probably defeat any attempt to check for memory leaks since you can no longer guarantee that all the memory allocated while running main has been deallocated.
Is the problem that the static items were never initialized, or is the problem that the static items weren't initialized when you needed to use them?
All static initialization is supposed to be finished before your main() runs. However, you can run into issues if you initialize on static object with another static object. (Note: this doesn't apply if you are using primitives such as int)
For example, if you have in file x.cpp:
static myClass x(someVals);
And in y.cpp:
static myClass y = x * 2;
It's possible that the system will try to instantiate y before x is created. In that case, the "y" variable will likely be 0, as x is likely 0 before it is initialized.
In general, the best solution for this is to instantiate the object when it is first used (if possible). However, I noticed above you weren't allowed to modify that file. Are the values from that file being used elsewhere, and maybe you can change how those values are accessed?
Read the manual page for the ld command and look at the -u option. If statinit.cpp defines anything that looks like a function then try naming it in -u. Otherwise choose a data object that's defined in statinit.cpp and name that in -u, and hope it works. I think it's best if you write the command line so the -u option comes immediately before your -l option for your library that has statinit's object code in it.
Of course the dynamic library solution is the best, but I've also been told it's possible to link the whole static library with the linker option:
-Wl,-whole-archive
before the library's -l option, and
-Wl,-no-whole-archive
after it (to avoid including other libraries as a whole, too).

How to initialize a shared library on Linux

I am developing a shared library using C++ under Linux, and I would like this library to use log4cxx for logging purposes. However, I'm not sure how to set this up. For log4cxx to work, I need to create a logger object. How can I make sure this object is created when my library is loaded?
I suspect that it will be easiest to create the logger object as a global variable and then use it from any of the source files of my library, declaring it as extern in the headers. But how can I have the logger created automatically once an application connects to the library?
I know that in DLLs for Windows, there's a thing as REASON_FOR_CALL == PROCESS_ATTACH; is there a similar thing under Linux?
In C++ under Linux, global variables will get constructed automatically as soon as the library is loaded. So that's probably the easiest way to go.
If you need an arbitrary function to be called when the library is loaded, use the constructor attribute for GCC:
__attribute__((constructor)) void foo(void) {
printf("library loaded!\n");
}
Constructor functions get called by the dynamic linker when a library is loaded. This is actually how C++ global initialization is implemented.
If you want your code to be portable you should probably try something like this:
namespace {
struct initializer {
initializer() {
std::cout << "Loading the library" << std::endl;
}
~initializer() {
std::cout << "Unloading the library" << std::endl;
}
};
static initializer i;
}
Using a global (or a local-static wrapped up in a function) is nice... but then you enter the land of static initialization fiasco (and the actual destruction is not pretty either).
I would recommend to have a look at the Singleton implementation of Loki.
There are various lifetime policies, one of which is Phoenix and will help you avoid this fiasco.
When you are at it, read Modern C++ Design which explains the problems encountered by the Singleton in depth as well as the uses for the various policies.