在C ++中,我是否要为自己不吃的东西付费? [英] In C++, am I paying for what I am not eating?

查看:72
本文介绍了在C ++中,我是否要为自己不吃的东西付费?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们考虑以下用C和C ++编写的世界示例:

Let's consider the following hello world examples in C and C++:

main.c

#include <stdio.h>

int main()
{
    printf("Hello world\n");
    return 0;
}

main.cpp

#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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆