在他的FAQ中,Bjarne Stroustrup说,当用gcc -O2编译时,使用C和C++的hello世界的文件大小是相同的.
参考:http://www.stroustrup.com/bs_faq.html#Hello-world
我决定尝试这个,这是C版本:
#include <stdio.h>
int main(int argc, char* argv[])
{
printf("Hello world!\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是C++版本
#include <iostream>
int main(int argc, char* argv[])
{
std::cout << "Hello world!\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这里我编译,大小不同:
r00t@wutdo:~/hello$ ls
hello.c hello.cpp
r00t@wutdo:~/hello$ gcc -O2 hello.c -o c.out
r00t@wutdo:~/hello$ g++ -O2 hello.cpp -o cpp.out
r00t@wutdo:~/hello$ ls -l
total 32
-rwxr-xr-x 1 r00t r00t 8559 Sep 1 18:00 c.out
-rwxr-xr-x 1 r00t r00t 8938 Sep 1 18:01 cpp.out
-rw-r--r-- 1 r00t r00t 95 Sep 1 17:59 hello.c
-rw-r--r-- 1 r00t r00t 117 Sep 1 17:59 hello.cpp
r00t@wutdo:~/hello$ size c.out cpp.out
text data bss dec hex filename
1191 560 8 1759 6df c.out
1865 608 280 2753 ac1 cpp.out
Run Code Online (Sandbox Code Playgroud)
我替换std::endl了\n它,它使二进制文件更小.我认为这个简单的内容会被内联,而且我很失望.
同样哇,优化的组件有几百行的装配输出?我可以使用sys_write用5个汇编指令编写hello world,所有额外的东西是什么?为什么C会在堆栈上添加一些额外的东西来设置?我的意思是,像50字节的汇编和8kb的C,为什么?
您正在查看容易被误解的混合信息.8559和8938字节的文件大小在很大程度上没有意义,因为它们主要是带有符号名称和其他misc信息的头文件,至少用于最小的调试目的.在一定程度上有意义的数字是size(1)你后来添加的输出:
r00t@wutdo:~/hello$ size c.out cpp.out
text data bss dec hex filename
1191 560 8 1759 6df c.out
1865 608 280 2753 ac1 cpp.out
Run Code Online (Sandbox Code Playgroud)
您可以通过使用-A选项获得更详细的细分size,但简而言之,这里的差异相当微不足道.
更有趣的是,Bjarne Stroustrup从未提及他是在谈论静态还是动态链接.在您的情况下,两个程序都是动态链接的,因此大小差异与stdio或iostream的实际大小成本无关; 您只是测量调用代码的成本,或者(更可能是基于其他注释/答案)C++异常处理支持的基本开销.现在,有一个共同的说法,即基于静态链接的C++基于iostream的hello世界甚至可以比printf基于它的小,因为编译器可以确切地看到使用哪些重载版本operator<<并优化掉不需要的代码(例如昂贵的浮动代码)点打印),而printf格式字符串的使用使得这在常见情况下变得困难并且通常是不可能的.但是,我从来没有见过一个C++实现,其中基于静态链接的基于iostream的hello程序可能接近于小于printfC中的基于iostream的hello程序.
我认为他将半 KB 视为舍入错误。两者都是“9 KB”,这就是您在典型文件浏览器中看到的内容。它们并不完全相同,因为在幕后,C 和 C++ 库完全不同。如果您已经熟悉您的反汇编程序,您可以自己查看差异的详细信息。
“额外的东西”是为了从标准库 shlib 导入符号,并处理 C++ 异常。奇怪的是,大部分 GCC 编译的 C 可执行文件被 C++ 异常处理表占用。我还没有想出如何使用 GCC 剥离它们。
endl 是内联的,但它包含打印\n字符和刷新流的调用,这些调用不是内联的。大小的差异是由于从标准库中导入的。
事实上,在任何具有动态加载库的系统上,单个千字节都无关紧要。自含代码,诸如在嵌入式系统上需要包括它使用标准库功能,以及C ++标准库往往比相应的C较重-<iostream>对<stdio.h>尤其如此。