3

看这个简单的程序

#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 字节。

为什么没有模板版本功能产生更多的二进制代码?

4

3 回答 3

3

这只是一个猜测,但是:

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

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

您必须检查二进制文件以确定发生了什么。如果您声明第一个staticinline.

于 2013-11-05T11:18:05.933 回答
2

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

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

您应该阅读生成的代码;也许这可以为您提供一些关于字节被剃掉的线索。

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

于 2013-11-05T11:09:21.450 回答
0

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

您可以通过简单地将函数的名称从 更改为 来看到这一点,foofoo1会将二进制文件增加一个字节。

剥离符号后,二进制文件大小相同

-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

strip a.out
于 2013-11-05T12:03:56.100 回答