The C++ standard since C++11 guarantees that std::cout
is "available for use in the constructors and destructors of static objects with ordered initialization (as long as is included before the object is defined)" (quoting from cppreference.com). I don't go into the details here (like, the role of std::ios_base::Init
etc.). See for example Is it safe to use standard library functions before main() has been called?
This guarantee, however, implies that whenever <iostream>
is included, the compiler has to ensure that some initialization code is added to the object file (unless there exist some optimizations by compiler/linker that make it possible to avoid this). I tried this with the Godbolt Compiler Explorer: For ARM gcc 5.4(linux) and -O2, the following code
int main() {
}
compiles to
main:
mov r0, #0
bx lr
whereas the code
#include <iostream>
int main() {
}
compiles to
main:
mov r0, #0
bx lr
_GLOBAL__sub_I_main:
stmfd sp!, {r4, lr}
ldr r4, .L4
mov r0, r4
bl std::ios_base::Init::Init() [complete object constructor]
mov r0, r4
ldr r2, .L4+4
ldr r1, .L4+8
bl __aeabi_atexit
ldmfd sp!, {r4, lr}
bx lr
.L4:
.word .LANCHOR0
.word __dso_handle
.word _ZNSt8ios_base4InitD1Ev
.LANCHOR0 = . + 0
Consequently, the mere inclusion of <iostream>
increases the code size and initialization time. For an individual file the impact might be considered as negligible. However, adding such include directives needlessly also to widely used library header files would IMO still count as avoidable waste of resources. I see it as another (even if not strong) argument for keeping your include directives clean.
That said, my question is, are there other header files defined by the standard (preferably latest version) that will also by mere inclusion (that is, without any actual reference to the contents of the header file) cause some code / data to be added to the resulting object file? Note that I do not limit this question to initialization scenarios - there might be other reasons.
Some additional notes:
- There could be impacts on symbol table size. This is not of interest for me - my interest is in code size, data size and performance.
- I am aware that a non-optimizing compiler might produce code (out-of-line) for inline functions even if the inline function is never called. You can assume that optimizations are enabled that prevent this to happen.