Почему ни одна шаблонная функция не делает больше двоичной, чем шаблонная функция

Смотрите эту простую программу

#include <cstdio>
#include <cstdlib>

void foo(){ printf("%d",1); }
int main(){ foo(); }

Я компилирую его с помощью gcc 4.6.4 -std= C++0x -O2 -g -Wall на Linux. И двоичный файл 11`238 байт.

Но этот код составляет 11`150 байт:

#include <cstdio>
#include <cstdlib>

template< bool = false> void foo(){ printf("%d",1); }
int main(){ foo(); }

Я также тестирую с помощью clang 3.3, результаты составляют 5684 байта и 5636 байтов соответственно.

Почему никакая функция версии шаблона не создает больше двоичного кода?

3 ответа

Это всего лишь предположение, но:

В первом примере foo имеет внешнюю связь и не является встроенным. Компилятор, вероятно, сгенерирует не встроенную версию, если ее использует другая единица перевода; и компоновщик может не удалить его, оставив его занимающим место в исполняемом файле.

Во втором примере foo является шаблоном, поэтому компоновщик с большей вероятностью сможет его исключить (поскольку он должен иметь возможность иметь дело с несколькими определениями, когда шаблон создается в нескольких единицах перевода).

Вы должны изучить двоичный файл, чтобы убедиться, что происходит. Возможно, вы увидите разницу, если объявите первый static или же inline,

Я думаю, что здесь нет общего ответа; все зависит от реализации компилятора.

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

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

Поможет ли это, если вы сделаете foo() в не шаблонной версии static? Возможно, это встроено в одном случае, но не в другом, и так далее.

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

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

После удаления символов файлы имеют одинаковый размер

-rwxr-xr-x 1 dejovivl dejovivl 6288 Nov  5 13:00 a.out*
-rwxr-xr-x 1 dejovivl dejovivl 6288 Nov  5 13:01 a.out*

чтобы удалить символы, используйте полосы:

strip a.out
Другие вопросы по тегам