Как влияют только библиотеки заголовков (Boost Like) на размер компиляции?

Когда я включаю заголовок hpp библиотеки boost в два блока перевода, компилируется ли код boost дважды (и размер двоичного файла удваивается по сравнению с традиционной предварительно скомпилированной библиотекой?)?

0

Решение

Вы задали два разных вопроса:

дважды ли код компиляции? Да, это так. Чистый эффект заключается в том, что время компиляции, вероятно, немного больше, поскольку компилятор должен переварить все заголовки для каждого модуля компиляции.

двоичный размер двойной? Нет, вероятно, нет, но это будет зависеть от вашего выбора флагов оптимизации. Шаблон, созданный в блоке A, будет условно использовать тот же код реализации, что и экземпляр, созданный в блоке B, с точно такой же параметры типа.

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

Встраивание никогда не возможно с бинарной библиотекой, и это одна из причин, почему ваш двоичный размер может увеличиться при использовании библиотек только с заголовками.

Вот пример, чтобы показать, как gcc разделяет реализацию шаблона, когда встраивание не включено:

a.cpp

#include <vector>

void test1() {
std::vector<int> myvec;
myvec.push_back(1);
}

b.cpp

#include <vector>

void test2() {
std::vector<int> myvec;
myvec.push_back(1);
}

m.cpp

extern void test1(),test2();

main() {
test1();
test2();
}

сборник

g++ -g -O0 -fno-inline -c m.cpp
g++ -g -O0 -fno-inline -c a.cpp
g++ -g -O0 -fno-inline -c b.cpp
g++ -o a.out a.o b.o m.o
objdump -S a.out |less

анализ objdump

void test1() {
// [snip]
myvec.push_back(1);
// [snip]
4008a0:       e8 d1 00 00 00          callq  400976 <_ZNSt6vectorIiSaIiEE9push_backERKi>

void test2() {
// [snip]
myvec.push_back(1);
// [snip]
401548:       e8 29 f4 ff ff          callq  400976 <_ZNSt6vectorIiSaIiEE9push_backERKi>

Обратите внимание, как та же реализация push_back используется (местоположение 400976), даже если он был скомпилирован в отдельные блоки компиляции.

3

Другие решения

Есть несколько заголовочных файлов boost, которые особенно велики (я смотрю на вас boost / lexical_cast.hpp), что приведет к увеличению размера двоичного файла. Тем не менее, компиляторы предлагают несколько вариантов, чтобы помочь:

MSVC имеет опцию / LTCG (генерация кода времени соединения)

GCC имеет -flto (я полагаю, включен с -O3)

Эти параметры обычно позволяют компоновщику отбрасывать неиспользуемые компоненты и уменьшать дублирование в модуле компиляции.

2

По вопросам рекламы [email protected]