I have a std::vector
which need to filled with some random values when library is loaded. but I see it is been reset after library is loaded. Is it because of global
and static
Library code:
static std::vector<uint8_t> g_randomNr{};
__attribute__((constructor)) void generateRandomNrAtStart(void)
{
static bool firstLoad = false;
g_randomNr.clear();
if (!firstLoad) {
firstLoad = true;
std::cout << "Library is loaded and generating first random number ...\n";
}
std::cout << "Generating random number ...\n";
for (int i = 0; i < 20; i ) {
g_randomNr.push_back(i);
}
std::cout << "Random number generated with length of " << g_randomNr.size() << "\n";
}
void getRandomNr(std::vector<uint8_t>& randomNr)
{
randomNr = g_randomNr;
}
Main code:
int main()
{
std::vector<uint8_t> randomNr{};
getRandomNr(randomNr);
std::cout << randomNr.size() << "\n";
return 0;
}
Output:
Library is loaded and generating first random number ...
Generating random number ...
Random number generated with length of 20
0
In the above output I expect 20 in cout main
function but I receive empty vector
CodePudding user response:
You are most likely suffering from a static initialization order fiasco.
I suggest lazy initialization of the vector
:
auto& instance() {
static std::vector<uint8_t> g_randomNr;
return g_randomNr;
}
Then in your shared library constructor:
__attribute__((constructor)) void generateRandomNrAtStart(void)
{
auto& g_randomNr = instance();
// ...
And also in the function making a copy:
void getRandomNr(std::vector<uint8_t>& randomNr)
{
randomNr = instance();
}
CodePudding user response:
Another option is to control the order of the vector initialization and constructor call with priorities:
__attribute__((init_priority(101))) static std::vector<uint8_t> g_randomNr{};
__attribute__((constructor(102))) void generateRandomNrAtStart() { ... }
Live demo: https://godbolt.org/z/bh9zj9cE3
Possibly OT to the problem: Note that using I/O (as std::cout
in your case) in a constructor can suffer from the very same problem. See, e.g., gcc linker extension __attribute__((constructor)) causes crash in main().