Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to know which headers are automatically included in C++

Tags:

c++

clang

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.

like image 793
Anurag Peshne Avatar asked Dec 18 '16 23:12

Anurag Peshne


3 Answers

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.

like image 184
Dietmar Kühl Avatar answered Sep 22 '22 21:09

Dietmar Kühl


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 #includes 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.

like image 37
Sam Varshavchik Avatar answered Sep 20 '22 21:09

Sam Varshavchik


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 #includes to each other. So MinGW can be a practical tool for checking portability.

like image 38
anatolyg Avatar answered Sep 21 '22 21:09

anatolyg