在C ++中,我是否要为自己不吃的东西付费? [英] In C++, am I paying for what I am not eating?
问题描述
让我们考虑以下用C和C ++编写的世界示例:
Let's consider the following hello world examples in C and C++:
#include <stdio.h>
int main()
{
printf("Hello world\n");
return 0;
}
#include <iostream>
int main()
{
std::cout<<"Hello world"<<std::endl;
return 0;
}
当我将它们编译为汇编时,C代码的大小为仅9行( gcc -O3
):
When I compile them in godbolt to assembly, the size of the C code is only 9 lines (gcc -O3
):
.LC0:
.string "Hello world"
main:
sub rsp, 8
mov edi, OFFSET FLAT:.LC0
call puts
xor eax, eax
add rsp, 8
ret
但是C ++代码的大小是22行( g ++ -O3
):
But the size of the C++ code is 22 lines (g++ -O3
):
.LC0:
.string "Hello world"
main:
sub rsp, 8
mov edx, 11
mov esi, OFFSET FLAT:.LC0
mov edi, OFFSET FLAT:_ZSt4cout
call std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
mov edi, OFFSET FLAT:_ZSt4cout
call std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)
xor eax, eax
add rsp, 8
ret
_GLOBAL__sub_I_main:
sub rsp, 8
mov edi, OFFSET FLAT:_ZStL8__ioinit
call std::ios_base::Init::Init() [complete object constructor]
mov edx, OFFSET FLAT:__dso_handle
mov esi, OFFSET FLAT:_ZStL8__ioinit
mov edi, OFFSET FLAT:_ZNSt8ios_base4InitD1Ev
add rsp, 8
jmp __cxa_atexit
...这要大得多。
在C ++中,您为自己所付的钱而闻名吃。因此,在这种情况下,我要支付的费用是什么?
It is famous that in C++ you pay for what you eat. So, in this case, what am I paying for?
推荐答案
您要支付的费用是调用繁重的库(不是和打印到控制台一样重)。您初始化 ostream
对象。有一些隐藏的存储。然后,您调用 std :: endl
,它不是 \n
的同义词。 iostream
库可帮助您调整许多设置,并减轻处理器而不是程序员的负担。这就是您要支付的费用。
What you are paying for is to call a heavy library (not as heavy as printing into console). You initialize an ostream
object. There are some hidden storage. Then, you call std::endl
which is not a synonym for \n
. The iostream
library helps you adjusting many settings and putting the burden on the processor rather than the programmer. This is what you are paying for.
让我们检查一下代码:
.LC0:
.string "Hello world"
main:
初始化ostream对象+ cout
Initializing an ostream object + cout
sub rsp, 8
mov edx, 11
mov esi, OFFSET FLAT:.LC0
mov edi, OFFSET FLAT:_ZSt4cout
call std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long)
再次调用 cout
打印新行并刷新
Calling cout
again to print a new line and flush
mov edi, OFFSET FLAT:_ZSt4cout
call std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)
xor eax, eax
add rsp, 8
ret
静态存储初始化:
_GLOBAL__sub_I_main:
sub rsp, 8
mov edi, OFFSET FLAT:_ZStL8__ioinit
call std::ios_base::Init::Init() [complete object constructor]
mov edx, OFFSET FLAT:__dso_handle
mov esi, OFFSET FLAT:_ZStL8__ioinit
mov edi, OFFSET FLAT:_ZNSt8ios_base4InitD1Ev
add rsp, 8
jmp __cxa_atexit
此外,区分语言和库也是必不可少的。
Also, it is essential to distinguish between the language and the library.
BTW,这只是故事的一部分。您不知道正在调用的函数中写了什么。
BTW, this is just a part of the story. You do not know what is written in the functions you are calling.
这篇关于在C ++中,我是否要为自己不吃的东西付费?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!