инициализация статического объекта при связывании со статической библиотекой - PullRequest
7 голосов
/ 07 сентября 2011

Каковы правила инициализации статического объекта, объявленного в другой общей библиотеке? Например, рассмотрим следующее:

файл X.hpp:

struct X {
   X ();
   static X const s_x;
};

struct Y {
   Y (X const &) {}
};

файл X.cpp:

#include "X.hpp"
#include <iostream>

X::X ()
{
   std::cout << "side effect";
}

X const X::s_x;

Я скомпилировал X.cpp в статической библиотеке libX.a и попытался связать с ним следующий исполняемый файл (файл main.cpp):

#include "X.hpp"

int main ()
{
     (void)X::s_x;  // (1)
     X x = s_x;     // (2)
     Y y = s_x;     // (3)
 }

только с (1) или (2) ничего не происходит. Но если я добавлю (3), статический объект будет инициализирован (то есть напечатан «побочный эффект»). (Я использую gcc 4.6.1).

Есть ли способ предсказать, что здесь произойдет?

Я не понимаю, как инструкция (2) не заставляет объект X::s_x быть сконструирован по умолчанию, тогда как (3) делает.

РЕДАКТИРОВАТЬ: команды построения:

g++ -c X.cpp
g++ -c main.cpp
ar rcs libX.a X.o
g++ -o test main.o -L. -lX

1 Ответ

5 голосов
/ 07 сентября 2011

По умолчанию на многих платформах, если ваша программа не ссылается на какие-либо символы из данного объектного файла в статической библиотеке, весь объектный файл (включая статические инициализаторы) будет удален.Таким образом, компоновщик игнорирует Xo в libX.a, потому что, похоже, он не используется.

Здесь есть несколько решений:

  1. Не зависит от побочных эффектовстатические инициализаторы.Это наиболее переносимое / простое решение.
  2. Ввести некоторую ложную зависимость для каждого файла, ссылаясь на фиктивный символ так, чтобы компилятор не мог видеть сквозь него (например, хранение адреса во внешне видимом глобальном элементе).
  3. Используйте какой-нибудь платформенный прием, чтобы сохранить рассматриваемые объекты.Например, в Linux вы можете использовать -Wl,-whole-archive a.o b.a -Wl,-no-whole-archive.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...