Suppose I have a a library (shared or static) with two file: lib.h
and lib.cpp
, in lib.h
:
#pragma once
struct Trigger {
struct TriggerImpl{
TriggerImpl();
};
inline static TriggerImpl trigger;
};
and lib.cpp
:
#include "lib.h"
#include <iostream>
struct LogConsole {
LogConsole() { std::cout << "LogConsole constructor" << std::endl; };
};
LogConsole log_console;
Trigger::TriggerImpl::TriggerImpl() {
std::cout << "Trigger constructor" << std::endl;
}
Then I link the library to an executable file main.cpp
:
#include <iostream>
// #include "lib.h" ///< uncomment this line and you will get different result!!!
int main() {
std::cout << "Done." << std::endl;
return 0;
}
With static link, (e.g. CMake target_link_library(... STATIC ...)
), you will get:
Done.
With dynamic linking, , (e.g. CMake target_link_library(... SHARED ...)
), you will get:
Trigger constructor
LogConsole constructor
Done.
However, if you uncomment the include
line, and use static link, you will get:
Trigger constructor
LogConsole constructor
Done.
My questions are:
- Why do dynamic linking and static linking will(or, will not) call the constructors of the global variables?
- I can understand that, include the header will initialize
trigger
, but why willlog_console
also initialized, what is the internal mechanism of compiler/linker?
Possible relative links are:
- Language Linkage
- Storage Duration
But I think this might be a “FEATURE” of some particular toolchain (what I’m using is: gcc 14.1.1
on my x64 desktop with Manjaro Linux).
adversarr is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1