Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Include of iostream leads to different binary

Compiling the following code

int main() {     return 0; } 

gives the assembly

main:         xorl    %eax, %eax         ret 

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

If now iostream is included

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

this assembly is created.

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 

Full optimization is turned on (-O3). https://gcc.godbolt.org/z/EtrEX8

Can someone explain, why including an unused header changes the binary. What is _GLOBAL__sub_I_main:?

like image 788
schorsch312 Avatar asked Aug 29 '18 13:08

schorsch312


People also ask

What is #include <iostream>?

iostream is an input output stream class. It is one of the streams in C++ used to handle output which is displayed on screen through Console or Terminal. iostream has members like cin, cout, endl, etc which let's you do the basic input, and work on the, input and then get the output.

What is the difference between iostream and header file?

If iostream is a library (which contains code) and iostream.h is a header file (which contains declaration), then why don't we include both in our program? You seems to have confused with library concept.

How to perform input and output using stream in C++?

In C++, we can perform input and output functionality by using Iostream. This stands for input and output, and this uses the stream to perform this functionality. In c++, stream stands or represents a sequence of character or byte which is used to perform io operations. In programming, the language stream contains the address of the destination.

What is streams in C++?

Streams are the supported abstraction/standard in C++ for performing IO. The most commonly used streams used in C++ are cin for input and cout for output. Effectively streams provide a language portable abstraction for interfacing with the local file system to read and write persisted data.


2 Answers

Each translation unit that includes <iostream> contains a copy of ios_base::Init object:

static ios_base::Init __ioinit; 

This object is used to initialize the standard streams (std::cout and its friends). This method is called Schwarz Counter and it ensures that the standard streams are always initialized before their first use (provided iostream header has been included).

That function _GLOBAL__sub_I_main is code the compiler generates for each translation unit that calls the constructors of global objects in that translation unit and also arranges for the corresponding destructor calls to be invoked at exit. This code is invoked by the C++ standard library start-up code before main is called.

like image 200
Maxim Egorushkin Avatar answered Oct 17 '22 14:10

Maxim Egorushkin


Including the iostream header has the effect of adding the definition of a static std::ios_base::Init object. The constructor of this static object initializes the standard stream objects std::cout, std::cerr and so forth.

The reason it's done is to avoid the static initialization order fiasco. It ensures the stream objects are properly initialized across translation units.

like image 22
StoryTeller - Unslander Monica Avatar answered Oct 17 '22 13:10

StoryTeller - Unslander Monica