I have some legacy code with some singleton classes that register themselves using constructors of global variables. It's a large codebase, that's compiled into one executable. I have tried to organize the code base and regroup code into libraries. A minimal example of the current code is
main.cpp
int main(int argc, char *argv[])
{
return 0;
}
Hash.cpp
#include <iostream>
class Hash
{
public:
Hash()
{
std::cout << "Hash\n";
}
};
Hash a;
and the current build configuration is
CMakeLists.txt
cmake_minimum_required(VERSION 3.26)
project(mcve)
add_executable(mcve main.cpp Hash.cpp)
Building the code and running the executable prints
Hash
I've modified the build configuration to
cmake_minimum_required(VERSION 3.26)
project(mcve)
add_library(Hash Hash.cpp)
add_executable(mcve main.cpp)
target_link_libraries(mcve Hash)
This creates a static library libHash.a
and links it to the executable. Compiling the same code and running the executable doesn't print anything. Why is the difference, and where is it described? Is it part of the C++ standard or of the compiler? Is it OS specific (Linux static libraries)? Is it undefined behavior?
a
inmain()
. I think the linker is optimizing it away and not loading that library. – Indeedmain
is entered or is delayed until the first non-initialization odr-use of a non-inline definition in the same translation unit as the one containing the variable definition. The behavior you see is just what compiler/linker chose for this implementation-definedness. – Kirman-Wl,--as-needed
which may be configured as default. – Kirman