web-dev-qa-db-fra.com

Inclure iostream conduit à différents binaires

Compilation du code suivant

int main() {
    return 0;
}

donne l'Assemblée

main:
        xorl    %eax, %eax
        ret

https://gcc.godbolt.org/z/oQvRDd

Si maintenant iostream est inclus

#include <iostream>   
int main() {
    return 0;
}

cette Assemblée est créée.

main:
        xorl    %eax, %eax
        ret
_GLOBAL__sub_I_main:
        subq    $8, %rsp
        movl    $_ZStL8__ioinit, %edi
        call    std::ios_base::Init::Init() [complete object constructor]
        movl    $__dso_handle, %edx
        movl    $_ZStL8__ioinit, %esi
        movl    $_ZNSt8ios_base4InitD1Ev, %edi
        addq    $8, %rsp
        jmp     __cxa_atexit

L'optimisation complète est activée (-O3). https://gcc.godbolt.org/z/EtrEX8

Quelqu'un peut-il expliquer pourquoi l'inclusion d'un en-tête inutilisé modifie le binaire. Quel est _GLOBAL__sub_I_main:?

37
schorsch312

Chaque unité de traduction qui comprend <iostream> contient une copie de ios_base::Init objet:

static ios_base::Init __ioinit;

Cet objet est utilisé pour initialiser les flux standard (std::cout et ses amis). Cette méthode est appelée Schwarz Counter et elle garantit que les flux standard sont toujours initialisés avant leur première utilisation (à condition que l'en-tête iostream ait été inclus).

Cette fonction _GLOBAL__sub_I_main est le code que le compilateur génère pour chaque unité de traduction qui appelle les constructeurs d'objets globaux dans cette unité de traduction et organise également l'appel des destructeurs correspondant à la sortie. Ce code est appelé par le code de démarrage de la bibliothèque standard C++ avant l'appel de main.

33
Maxim Egorushkin

L'inclusion de l'en-tête iostream a pour effet d'ajouter la définition d'un objet statique std::ios_base::Init. Le constructeur de cet objet statique initialise les objets de flux standard std::cout, std::cerr Et ainsi de suite.

La raison pour laquelle cela est fait est d'éviter le fiasco de l'ordre d'initialisation statique. Il garantit que les objets de flux sont correctement initialisés dans les unités de traduction.

23
StoryTeller