Включение iostream приводит к разным двоичным файлам - PullRequest
0 голосов
/ 29 августа 2018

Компилирование следующего кода

int main() {
    return 0;
}

дает сборку

main:
        xorl    %eax, %eax
        ret

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

Если сейчас iostream включено

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

эта сборка создана.

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

Включена полная оптимизация (-O3). https://gcc.godbolt.org/z/EtrEX8

Может кто-нибудь объяснить, почему включение неиспользуемого заголовка меняет двоичный файл. Что такое _GLOBAL__sub_I_main:?

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Каждая единица перевода, включающая <iostream>, содержит копию объекта ios_base::Init:

static ios_base::Init __ioinit;

Этот объект используется для инициализации стандартных потоков (std::cout и его друзей). Этот метод называется Счетчик Шварца , и он гарантирует, что стандартные потоки всегда инициализируются перед их первым использованием (при условии, что был включен заголовок iostream).

Эта функция _GLOBAL__sub_I_main - это код, который генерирует компилятор для каждой единицы перевода, которая вызывает конструкторы глобальных объектов в этой единице перевода, а также организует вызов соответствующих деструкторов при выходе. Этот код вызывается кодом запуска стандартной библиотеки C ++ до вызова main.

0 голосов
/ 29 августа 2018

Включение заголовка iostream приводит к добавлению определения статического объекта std::ios_base::Init. Конструктор этого статического объекта инициализирует стандартные объекты потока std::cout, std::cerr и т. Д.

Причина, по которой это сделано, состоит в том, чтобы избежать фиаско статического порядка инициализации. Это обеспечивает правильную инициализацию потоковых объектов в единицах перевода.

...