为什么没有模板函数比模板函数更二进制

Why no template function makes more binary than template function

本文关键字:函数 二进制 为什么      更新时间:2023-10-16

>看这个简单的程序

#include <cstdio>
#include <cstdlib>
void foo(){ printf("%d",1); }
int main(){ foo(); }

我在 linux 上用 gcc 4.6.4 -std=c++0x -O2 -g -Wall 编译它。和二进制文件 11'238 字节。

但是这段代码会产生 11'150 字节:

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

我也用clang 3.3进行测试,结果是5684字节和5636字节。

为什么没有模板版本函数制作更多的二进制代码?

这只是一个猜测,但是:

在第一个示例中,foo具有外部链接,并且不是内联的。编译器可能会生成一个非内联版本,以防另一个翻译单元使用它;并且链接器可能不会删除它,从而占用可执行文件中的空间。

在第二个示例中,foo 是一个模板,因此链接器更有可能将其省略(因为当模板在多个翻译单元中实例化时,它需要能够处理多个定义)。

您必须检查二进制文件以确定发生了什么。如果您将第一个声明为staticinline,也许您会发现差异。

我认为这里没有通用的答案;这在很大程度上取决于编译器的实现。

此外,差异非常小,因此甚至很难确定这是一个正确的结论。

你应该阅读生成的代码;也许这可以给你一些关于字节在哪里被剃掉的线索。

如果您在非模板版本中static foo()是否有帮助?也许它在一种情况下是内联的,但在另一种情况下不是,依此类推。

输出二进制文件取决于编译器的实现。在编译期间,它将生成符号表,这取决于函数名称。模板函数转换为较长的符号名称,这会增加二进制文件的大小。

你可以通过简单地将函数的名称从 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