Inizializzazione statica e distruzione dei globali di una libreria statica che non si verificano con g ++
-
05-07-2019 - |
Domanda
Fino a qualche tempo fa, pensavo che una libreria statica fosse solo una raccolta di file di oggetti .o, semplicemente archiviandoli e non facendoli gestire diversamente. Ma il collegamento con un oggetto .o e il collegamento con una libreria statica. Contenente questo oggetto .o apparentemente non sono gli stessi . E non capisco perché ...
Consideriamo i seguenti file di codice sorgente:
// main.cpp
#include <iostream>
int main(int argc, char* argv[]) {
std::cout << "main" << std::endl;
}
// object.hpp
#include <iostream>
struct Object
{
Object() { std::cout << "Object constructor called" << std::endl; }
~Object() { std::cout << "Object destructor called" << std::endl; }
};
// object.cpp
#include "object.hpp"
static Object gObject;
Compiliamo e link ed eseguiamo questo codice:
g++ -Wall object.cpp main.cpp -o main1
./main1
> Object constructor called
> main
> Object destructor called
Viene chiamato il costruttore e il distruttore dell'oggetto globale gObject.
Ora creiamo una libreria statica dal nostro codice e usiamola (link) in un altro programma:
g++ -Wall -c object.cpp main.cpp
ar rcs lib.a object.o
g++ -Wall -o main2 main.o lib.a
./main2
> main
- Il costruttore e il distruttore di gObject non vengono chiamati ... perché?
- Come farli chiamare automaticamente?
Grazie.
Soluzione
.a
contengono diversi .o
ma non sono collegate a meno che non le si faccia riferimento dall'app principale.
.o
collega sempre il file standalone.
Quindi i file .o
nel linker vanno sempre all'interno, referenziati o meno, ma dai file .a
fanno riferimento solo ai file oggetto .o
sono collegati.
Come nota, non è necessario inizializzare gli oggetti globali statici finché non si fa effettivamente riferimento a qualcosa nell'unità di compilazione, la maggior parte dei compilatori li inizializzerà prima di main, ma l'unico requisito è che vengano inizializzati prima di qualsiasi funzione del l'unità di compilazione viene eseguita.