10

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.

Community
  • 1
  • 1
Anurag Peshne
  • 1,547
  • 12
  • 29
  • 1
    open the header files you included? Why would it be important anyway? – rfreytag Dec 18 '16 at 23:56
  • Note that there is no need to have a minimal (and thus nonportable!) set of includes for standard headers; redundant includes are harmless. `cassert`, I think, is the *only* header that does anything interesting when included multiple times. –  Dec 18 '16 at 23:56
  • 4
    Never rely on such implicitly included headers, it's an implementation detail and can change at any time. Always explicitly include the functionality you need. – AliciaBytes Dec 18 '16 at 23:59
  • 1
    @pfannkuchen_gesicht I submitted a homework which works perfectly on my computer but the TA faced problem compiling it. So I was wondering is there a way to know which headers were included automatically so that I can bulletproof my code. – Anurag Peshne Dec 19 '16 at 00:01
  • @RaphaelMiedl true, I just wanted to know if there is a simple way to know since sometimes it's not that obvious, honestly I don't know which part of my code need definitions from algorithm header. – Anurag Peshne Dec 19 '16 at 00:03
  • 1
    your compiler should give you some warnings about implicit declarations. Either way, if you want to use a function, include the header for it accordingly. Don't rely on includes of includes. – rfreytag Dec 19 '16 at 00:04
  • 4
    @Anarug: Ah, it would improve your question to put the motivation in the question -- or even rephrase the question to be about what you actually want to know: how to ensure you have all the `#include`s you need to be portable rather than leaving some headers implicitly included. –  Dec 19 '16 at 00:06
  • 1
    @AnuragPeshne if you use a reference like [cppreference](http://en.cppreference.com/w/) it should tell you what header you need to include for whatever you're looking at. Also turn up compiler warnings. – AliciaBytes Dec 19 '16 at 00:06
  • 4
    @Raphael: The question of "what do I need to include for this one thing" is very different from "I've written thousands of lines of code; how do I check I've explicitly included everything needed?" –  Dec 19 '16 at 00:07
  • @Hurkyl thanks for the suggestion, I've updated the question. – Anurag Peshne Dec 19 '16 at 00:12
  • Use a second compiler with a different std lib. –  Dec 19 '16 at 09:19
  • 1
    A side note: Eclipse CDT has the functionality to [organize includes](http://www.eclipse.org/community/eclipse_newsletter/2013/october/article3.php) - that is, roughly speaking, to make sure that the includes are sufficient and not redundant. Some powerful techniques are employed there. I have only done a very basic test a while ago, and can say that it basically works, but have not yet tried it for really complex applications. – Marco13 Dec 19 '16 at 22:44
  • @Marco13 Your hint to use CDT's "organize include" functionality is excellent. Thank you very much for pointing this out! It seems to me that this is the best answer to this question. – RHertel Jul 19 '19 at 10:09
  • @RHertel I just added an answer here, mentioning the tool, but with a small disclaimer: 1. There is https://stackoverflow.com/questions/3644293/are-there-tools-that-help-organizing-includes , and 2. Asking for external tools is nowadays considered to be "Off Topic" on stack overflow (therefore, I added some reasoning of why it is hard or impossible to solve the problem manually...) – Marco13 Jul 19 '19 at 11:07

4 Answers4

5

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.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • I'm a C++ noob, I naively considered mutex locks are defined in thread header, now my compiler automatically included and I considered all my includes are enough. So the only way is to know that I have included all headers is go through documentation and see where they are defined, is this correct? – Anurag Peshne Dec 19 '16 at 00:19
  • @AnuragPeshne: yes, I fear that's correct. I had tried to create headers which make only the names mandated available but that's not as trivial as I had hoped it would be. I'm not aware of any other attempt to do that. – Dietmar Kühl Dec 19 '16 at 00:22
  • It is quite clear that one should not rely on indirect includes, and I don't think that this was what the OP was asking about this. The problem is quite the opposite, i.e., how to detect indirect includes that should instead be included explicitly. This is important to ensure the portability of a code. If a programmer forgets an include, a code might still compile on one machine (due to indirect includes), but fail on other. Recognizing and correcting such situations can be difficult, especially in large codes. – RHertel Jul 19 '19 at 10:19
3

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.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • I tried passing `-E` flag and you are correct, it is giving info about all the headers included. But it prints a lot of noise, which can easily confuse a newbie (there are 4 different types of mutex included). – Anurag Peshne Dec 19 '16 at 00:35
  • 2
    But there is no guarantee that the result will be the same as someone using a different standard library, right? Which is the context of the question. – rici Dec 19 '16 at 00:38
2

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.

anatolyg
  • 26,506
  • 9
  • 60
  • 134
1

This question has considerable overlap with Are there tools that help organizing #includes? , and the latter would nowadays be considered as "Off topic" because it's asking for external tools/resources. Strictly speaking, this question is only about a way to find indirect includes, but the goal is certainly the same.


The problem of using "the right" include statements is distressingly hard. What was described in the question is mainly about indirect inclusion: One header includes a certain symbol, but on another machine with another compiler and another header, the symbol might not be included.

Some of the comments and other answers suggested seemingly pragmatic but unrealistic approaches:

  • Try it out with another compiler: This is brittle, and does not tell you anything about a possible third compiler
  • Read the included headers, to see which other headers they include: No. The idea of headers is exactly the opposite, namely not having to read them, but just to use the API that they offer
  • Generate preprocessor output and write a tool to solve the problem semi-automatically: Nope. This won't solve the problem of different header versions anyhow.
  • Explicitly include the headers that you need for the thing that you are using: This is basically impossible to maintain. When you move one function from your file to another during a refactoring, you never know which includes you can safely remove in one file, and which ones you have to add to the other one.

    (And when you change your includes, you'll likely break third-party code that included your headers, because everybody is facing the same problem...)

All this does not cover the caveat that indirect inclusion is not always a problem, but sometimes intended: When you want to use std::vector, you'd #include <vector>, and not #include <bits/stl_vector.h>, even though the latter contains the definition...


So the only realistic solution for this is to rely on tools that support the developer. Some tools are mentioned in the answers of Are there tools that help organizing #includes? , and originally, I mentioned CDT in a comment to the question three years ago, but I think it's worth being mentioned here as well:

Eclipse CDT (C/C++ Development Tooling)

This is an IDE that offers an "Organize Includes" feature. The features is described in the article at https://www.eclipse.org/community/eclipse_newsletter/2013/october/article3.php , which points out the difficulties and caveats (and I mentioned some of them above), and how they are tackled in CDT.

I have tried this out (quite a while ago), although only in a very simple test project. So I can say that it basically works, but considering the complexity of the task, this comes with a disclaimer: It's close to magic, but there might still be cases where it fails.

C++ is not intended to be parsed and compiled. This statement is true, because one of my previous answers here on stack overflow contained the line #define not certainly.

The article also points to another tool:

Include What You Use

I have not tried this out, but it seems to be quite actively maintained. The documentation pages also list some of the difficulties and goals. From a first glance, it does not seem to be as powerful and configurable as CDT (and of course, does not come in an IDE), but some might want to try it out.

Marco13
  • 53,703
  • 9
  • 80
  • 159