Is there any way to know which headers are automat

2020-04-03 07:58发布

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.

标签: c++ clang
4条回答
够拽才男人
2楼-- · 2020-04-03 08:11

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.

查看更多
仙女界的扛把子
3楼-- · 2020-04-03 08:15

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.

查看更多
看我几分像从前
4楼-- · 2020-04-03 08:24

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.

查看更多
相关推荐>>
5楼-- · 2020-04-03 08:26

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.

查看更多
登录 后发表回答