c++ - 为什么 C++ Hello World 二进制文件比等效的 C 二进制文件大?

标签 c++ c size

在他的常见问题解答中,Bjarne Stroustrup 说当使用 gcc -O2 编译时,使用 C 和 C++ 的 hello world 的文件大小是相同的。

引用: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;
}

这是C++版本

#include <iostream>

int main(int argc, char* argv[])
{
    std::cout << "Hello world!\n"; 
    return 0;
}

我这里编译,大小不一样:

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

我用 \n 替换了 std::endl ,它使二进制文件更小。我认为应该内联这么简单的东西,但我很失望,但事实并非如此。

还有哇,优化后的程序集有数百行程序集输出?我可以使用 sys_write 用大约 5 条汇编指令编写 hello world,所有这些额外的东西怎么了?为什么 C 在堆栈上放置一些额外的设置?我的意思是,比如 50 字节的汇编代码与 8kb 的 C 代码,为什么?

最佳答案

您正在查看很容易被误解的混合信息。 8559 和 8938 字节的文件大小在很大程度上是没有意义的,因为它们主要是带有符号名称和其他杂项信息的 header ,至少用于最小的调试目的。 有些有意义的数字是您稍后添加的 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

您可以通过使用 -Asize 选项获得更详细的 segmentation ,但简而言之,这里的差异相当微不足道。

更有趣的是,Bjarne Stroustrup 从未提及他是在谈论静态链接还是动态链接。在您的情况下,这两个程序都是动态链接的,因此大小差异与 stdio 或 iostream 的实际大小成本无关;您只是在衡量调用代码的成本,或者(更有可能是基于其他评论/答案)C++ 异常处理支持的基本开销。现在,有一种常见的说法是静态链接的 C++ 基于 iostream 的 hello world 甚至可以比基于 printf 的 hello world 更小,因为编译器可以准确地看到使用了哪些 operator<< 的重载版本并优化掉不需要的代码(例如昂贵的浮点打印),而 printf 对格式字符串的使用使得这在常见情况下变得困难并且通常不可能。但是,我从未见过 C++ 实现中静态链接的基于 iostream 的 hello 程序可以接近于 C 中基于 printf 的 hello 程序一样小,小得多。

关于c++ - 为什么 C++ Hello World 二进制文件比等效的 C 二进制文件大?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25614505/

相关文章:

javascript - 如何根据其内容调整ExtJS窗口宽度?

html - 为什么我的放大文本大小的辅助工具不起作用?

c++ - ecx 寄存器是否用于传递静态函数调用中的参数之一?

c++ - 由于更新到 Xcode 10 文件未找到错误/派生数据

c++ - 绑定(bind)到实例的确定性随机数生成器(独立于线程)

c - mmap 无法分配超过 2GB 的连续数据

c++ - 在 Linux 上分析数据库密集型代码

C: 字符串中的字符与 '\0' 之间的比较不起作用?

c - 哪个更适合windows? pthreads 还是 CreateMutex?

c++ - 二维 vector 的大小