This is a follow-up question for this which says that
In C++, unlike C, standard headers are allowed to #include other standard headers.
Is there any way to know which headers were automatically included, since it may be difficult to guess which symbols are defined in which headers.
Motivation: My homework compiles and works correctly on my computer but TA told me it was not compiling and needed couple of headers (mutex and algorithm) to compile. How I can be sure the code I submit in future be bulletproof.
My compiler is not giving any warning about implicit declaration.
I'm using clang++ -std=c++11
to compile my code.
The standard lists the symbols made available by each header. There are no guarantees beyond that, neither that symbols which are obviously used nor that there not all symbols are declared. You'll need to include each header for any name you are using. You should not rely on indirect includes.
On the positive side, there is no case in the standard library where any of the standard library headers requires extra headers.
If you want to know what other headers a particular header file pulls, the easiest way to do so is to run the include file through the compiler's preprocessor phase only, instead of compiling it fully. For example, if you want to know what <iostream>
pulls in, create a file containing only:
#include <iostream>
then preprocess it. With gcc
, the -E
option runs the preprocessor only, without compiling the file, and dumps the preprocessed file to standard output. The resulting output begins with:
# 1 "t.C"
That's my one-line source file.
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
Apparently, gcc
automatically pulls in this header file, no matter what. This can be ignored.
# 1 "<command-line>" 2
# 1 "t.C"
# 1 "/usr/include/c++/6.2.1/iostream" 1 3
Ok, now we finally get to the actual #include
statement in my one-line source file. That's where my <iostream>
is:
# 36 "/usr/include/c++/6.2.1/iostream" 3
# 37 "/usr/include/c++/6.2.1/iostream" 3
# 1 "/usr/include/c++/6.2.1/x86_64-redhat-linux/bits/c++config.h" 1 3
Ok, so iostream
itself #include
s this "c++-config.h" header file, obviously an internal compiler header.
If I keep going, I can see that <iostream>
pulls in, unsurprisingly, <ios>
, <type_traits>
, as well as C header files like stdio.h
.
It shouldn't be too hard to write a quick little script that takes a header file, runs the compiler in preprocessing phase, and produces a nice, formatted list of all header files that got pulled in.
As far as I know, there is no way to do what you want.
If you try to compile your code on several example platforms, and it is successful, there is a greater chance that it will compile on any other platform, but there is no easy way to be sure.
In my experience, MinGW C++ headers use fewer #include
s to each other. So MinGW can be a practical tool for checking portability.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With