Why is a C++ Hello World binary larger than the equivalent C binary?

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-04 13:12:21

问题


In his FAQ, Bjarne Stroustrup says that when compiled with gcc -O2, the file size of a hello world using C and C++ are identical.

Reference: http://www.stroustrup.com/bs_faq.html#Hello-world

I decided to try this, here is the C version:

#include <stdio.h>

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

And here is the C++ version

#include <iostream>

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

Here I compile, and the sizes are different:

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

I replaced std::endl with \n and it made the binary smaller. I figured something this simple would be inlined, and am dissapointed it's not.

Also wow, the optimized assemblies have hundreds of lines of assembly output? I can write hello world with like 5 assembly instructions using sys_write, what's up with all the extra stuff? Why does C put some much extra on the stack to setup? I mean, like 50 bytes of assembly vs 8kb of C, why?


回答1:


You're looking at a mix of information that's easily misinterpreted. The 8559 and 8938 byte file sizes are largely meaningless since they're mostly headers with symbol names and other misc information for at least minimal debugging purposes. The somewhat meaningful numbers are the size(1) output you added later:

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

You could get a more detailed breakdown by using the -A option to size, but in short, the differences here are fairly trivial.

What's more interesting is that Bjarne Stroustrup never mentioned whether he was talking about static or dynamic linking. In your case, both programs are dynamic-linked, so the size differences have nothing to do with the actual size cost of stdio or iostream; you're just measuring the cost of the calling code, or (more likely, based on the other comments/answer) the base overhead of exception-handling support for C++. Now, there is a common claim that a static-linked C++ iostream-based hello world can be even smaller than a printf-based one, since the compiler can see exactly which overloaded versions of operator<< are used and optimize out unneeded code (such as expensive floating point printing), whereas printf's use of format strings makes this difficult in the common case and impossible in general. However, I've never seen a C++ implementation where a static-linked iostream-based hello program could come anywhere near close to being as small as, much less smaller than, a printf-based one in C.




回答2:


I think he's treating the half kilobyte as a rounding error. Both are "9 kilobytes" and that's what you'll see in a typical file browser. They aren't exactly the same because, under the hood, the C and C++ libraries are quite different. If you're already familiar with your disassembler, you can see the details of the difference for yourself.

The "extra stuff" is for the sake of importing symbols from the standard library shlib, and handling C++ exceptions. Strangely enough, much of the GCC-compiled C executable is taken up by C++ exception handling tables. I've not figured out how to strip them using GCC.

endl is inlined, but it contains calls to print the \n character and flush the stream, which are not inlined. The difference in size is due to importing those from the standard library.

In truth, individual kilobytes seldom matter on any system with dynamically-loaded libraries. Self-contained code such as on an embedded system would need to include the standard library functionality it uses, and the C++ standard library tends to be heavier than its C counterpart — <iostream> vs. <stdio.h> in particular.



来源:https://stackoverflow.com/questions/25614505/why-is-a-c-hello-world-binary-larger-than-the-equivalent-c-binary

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!