inicialização estática e destruição de globals de uma biblioteca estática não acontecendo com g ++
-
05-07-2019 - |
Pergunta
Até algum tempo atrás, eu pensei que uma biblioteca .a estática era apenas uma coleção de .o arquivos objeto, apenas arquivá-los e não torná-los tratados de forma diferente. Mas ligação com um objeto .o e ligando com uma biblioteca .a estática que contém esse objeto .o aparentemente não são os mesmos . E eu não entendo por que ...
Vamos considerar os seguintes arquivos de código fonte:
// 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;
Vamos compilar e link e executar este código:
g++ -Wall object.cpp main.cpp -o main1
./main1
> Object constructor called
> main
> Object destructor called
O construtor de um processo de destruição do objeto gobject mundial é chamado.
Agora vamos criar uma biblioteca estática do nosso código e uso (link)-lo em outro programa:
g++ -Wall -c object.cpp main.cpp
ar rcs lib.a object.o
g++ -Wall -o main2 main.o lib.a
./main2
> main
- construtor e destruidor de gobject não são chamados ... por quê?
- Como tê-los chamado automaticamente?
Graças.
Solução
bibliotecas .a
estáticos contêm vários .o
mas eles não estão ligados a menos que você referenciá-los a partir do aplicativo principal.
.o
arquivos de link autônomo sempre.
arquivos .o
Assim, no vinculador sempre ir para dentro, referenciados ou não, mas a partir de arquivos .a
apenas arquivos objeto .o
referenciados são vinculados.
Como uma nota, objetos globais estáticas não são obrigados a ser inicializado até que você realmente referenciar qualquer coisa na unidade de compilação, a maioria dos compiladores irá inicializar todos eles antes de principal, mas a única exigência é que eles são inicializados antes de qualquer função do unidade de compilação é executado.