Умный компоновщик может распознать, когда два разных тела функций идентичны, и объединить их в один символ.В MSVC это называется «сворачивание КОМДАТА» и «удаление дубликатов» в большинстве других мест.Например, следующие две функции могут компилироваться одинаково на PPC, хотя они принимают разные типы, потому что типы имеют одинаковый размер и ведут себя одинаково в данной ситуации.
template<typename T>
GetLowBit( T foo ) { return T & 1; }
GetLowBit<unsigned long>(ulong x); // compiles to "li r4, 1 ; and r3, r3, r4 ; blr "
GetLowBit<signed long>(long x); // also compiles to "li r4, 1 ; and r3, r3, r4 ; blr "
и поэтому компоновщик может сделать обаих «имена» указывают на то же место, как и раньше, так что звонок на GetLowBit<unsigned long>
идет на тот же адрес, что и звонок на GetLowBit<signed long>
.Таким образом, в общем случае можно сложить различные экземпляры шаблонов функций, которые все работают с одинаковыми типами размеров одинаковыми способами.(В частности, контейнеры, в которых хранятся указатели или перечисления, как правило, складываются вместе.)
Это не просто для функций шаблона.Некоторые компоновщики могут заметить, когда любые две функции имеют идентичные тела, и объединить их.В частности, я вижу, что MSVC имеет тенденцию сворачивать каждую виртуальную функцию, которая не делает ничего, кроме возврата в одну uber-функцию, например, для
class A
{
virtual void nothing() {};
}
class B
{
virtual void empty() {};
}
Я часто вижу (в дизассемблере во время отладки чего-то еще), что записи vtableдля nothing
и empty
оба указывают на одно и то же тело функции, которое, в свою очередь, является просто ret
.
Можете ли вы рассчитывать на это?Нет. Это функция, которую интеллектуальный компоновщик может предоставлять для функций , когда он их замечает .Ваш компоновщик может быть глупым - там много паршивых компиляторов.Это может произойти, только если вы предоставите определенные аргументы команды.Это может произойти для некоторых функций, но не для других по причинам, известным только компоновщику.Он может даже отличаться от сборки к сборке в зависимости от того, что еще есть в программе.
В общем, да, это может произойти, и когда это произойдет, это может быть хорошей экономией вразмер исполняемого файла.Но вы не можете рассчитывать на то, что это произойдет, если вы не очень хорошо знакомы со своим компоновщиком и всеми его функциями.