Статическая инициализация и уничтожение глобальных переменных статической библиотеки не происходит в g++.

StackOverflow https://stackoverflow.com/questions/1804606

Вопрос

До недавнего времени я думал, что статическая библиотека .a — это просто набор объектных файлов .o, которые просто архивируются, а не обрабатываются по-другому.Но связывание с объектом .o и соединение со статической библиотекой .a, содержащей этот объект .o, по-видимому, не одно и то же.И я не понимаю, почему...

Давайте рассмотрим следующие файлы исходного кода:

// 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;

Давайте скомпилируем и связь и запустите этот код:

g++ -Wall object.cpp main.cpp -o main1
./main1
> Object constructor called
> main
> Object destructor called

Вызывается конструктор и деструктор глобального объекта gObject.

Теперь давайте создадим статическая библиотека из нашего кода и использовать (ссылку) его в другой программе:

g++ -Wall -c object.cpp main.cpp
ar rcs lib.a object.o
g++ -Wall -o main2 main.o lib.a
./main2
> main
  • Конструктор и деструктор gObject не вызываются...почему?
  • Как сделать, чтобы они автоматически вызывались?

Спасибо.

Это было полезно?

Решение

.a статические библиотеки содержат несколько .o но они не связаны, если вы не ссылаетесь на них из основного приложения.
.o файлы всегда имеют отдельную ссылку.

Так .o файлы в компоновщике всегда попадают внутрь, независимо от того, есть ли ссылка на них, но из .a файлы, на которые ссылаются только .o Объектные файлы связаны.

Обратите внимание: статические глобальные объекты не требуется инициализировать до тех пор, пока вы фактически не ссылаетесь на что-либо в модуле компиляции. Большинство компиляторов инициализируют их все перед main, но единственное требование состоит в том, чтобы они были инициализированы до того, как будет получена какая-либо функция модуля компиляции. казнен.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top