6

On Linux, what is a fast way to identify what are the necessary #include statements that I need for a C++ project?

I mean, let's say someone gives you a snippet from the web, but fails to provide the necessary #include statements. Is there potentially a way where you can run a Linux command or compiler command option and identify which functions or classes are missing, and, as a bonus, identify on the hard drive where I might have these things in a header file.

Volomike
  • 23,743
  • 21
  • 113
  • 209
  • 8
    Read the manual. I'm not being flippant, I don't think there's a better way. – john Sep 20 '13 at 18:29
  • Please define what you mean by "fast". – i_am_jorf Sep 20 '13 at 18:29
  • @john I just thought perhaps that there might be a command you type and it tries to identify among existing header files which functions or classes it needs. If not, then let me know and I'll promptly close this request. – Volomike Sep 20 '13 at 18:36
  • @Volomike If there is then it will be an option on your compiler, since it has the necessary knowledge to parse C++ source. Don't close the question, it's a perfectly good one. – john Sep 20 '13 at 18:37
  • @Volomike: do you want to add stuff or to strip unnecessary stuff? – thokra Sep 20 '13 at 18:41
  • I don't know of any such program, although it might be useful for some disorganized people such indexer of header files. Anyway, the "proper" way to do it is: start writing the code, when you need some functionality, include the corresponding header. – lvella Sep 20 '13 at 18:42
  • Fastest way - compile the program without including files you need and the compiler should tell you. Or `#include ` – smac89 Sep 20 '13 at 18:59
  • @thokra I will edit the question. I need to know what `#include` is necessary for a given snippet that I might find on the web, if the snippet doesn't have the #include. – Volomike Sep 20 '13 at 19:03
  • 1
    Oh in that case, don't try and hack together snippets from all four corners of the globe, understand what it does, and if it's a library learn how to specify libraries to the compiler. – Alec Teal Sep 20 '13 at 19:09
  • @AlecTeal: I'm sorry, ehm, what? O_o – thokra Sep 20 '13 at 19:26
  • @thokra when you see bits of code on line and try and hack them together, you may ask "is there a faster way to get the right include (and/or libraries)" if this is the case, hacking together code like that ought not be done. – Alec Teal Sep 20 '13 at 19:27
  • @AlecTeal: The OP is asking for a way to be able to compile already existing code they're handed by someone else. No one said anything about hacking stuff together. – thokra Sep 20 '13 at 19:30
  • @thokra seems legit. Please no more comments directed at me now. This question has received far to much attention already. – Alec Teal Sep 20 '13 at 19:32
  • Afaik, C++ as a language is subject to halting problem. So compiler can't know if C++ code is valid until it finishes compiling it. Is it that hard to compile *single* *.cpp file and read errors? I mean, if you're seriously using the language, you should already know common C++ includes and should be able to spot common missing includes by reading error messages. – SigTerm Sep 20 '13 at 19:48

5 Answers5

5

Basically you need some analyzer to parse your sources and headers and build a complete dependency graph which it spits out in the end for you to read and process further.

I'd follow john's advice on g++ and Clang for this purpose but I highly doubt they got what it takes.

What you actually can do, at least with g++, is print out a graph for already existing includes. Use the -H option to print a tree or -M to get a list.

I also refer you to this related topic: Tool to track #include dependencies

Not exactly what you want, but the tools mentioned there might be helpful.

Community
  • 1
  • 1
thokra
  • 2,874
  • 18
  • 25
2

I think Clang's "include-what-you-use" tool is what you want.

user541686
  • 205,094
  • 128
  • 528
  • 886
-1

If, by necessary you mean minimal (i.e. if A includes B and B includes C then A doesn't need to include C) I don't know of a fast way.

One good approach, however, is for each cpp file to include its own header file first (after any precompiled headers.) That insures that each header file includes (directly or indirectly) all the header files it needs to define the symbols used in the header.

Also a project of reasonable size should be designed in layers such that Layer A knows about/depends on layer B which depends on layer C, etc, but lower layers never include higher layers (i.e. C never includes anything from layer A)

In that case the includes in each cpp or hpp should be in Layer order (A, B, C). If you do this it is fairly easy to check to see if any of the layer C headers can be eliminated (comment them out temporarily) because one of the includes that comes before them has already included them. This happens quite a lot and can significantly reduce the number of #includes in each file.

Having said all of that, this is a much less critical issue than it used to be because compilers are smarter. A combination of #pragma once and precompiled headers can keep build times down without requiring that you spend a lot of time optimizing includes.

Dale Wilson
  • 9,166
  • 3
  • 34
  • 52
  • Back when it did matter a lot, I used to have #else clauses on the header guards that Alec Teal mentioned with #pragma message("Unnecessary include of " __FILE__) Again not a fast way to solve the problem but it would let you do some include optimization. – Dale Wilson Sep 20 '13 at 18:54
  • I think it is more important these days that one appeases the IDE one uses, I also don't think it's been a problem for a long time, code files are rarely significantly larger than 1mb, the pre-processor kicks in before parsing (or even tokenising - beyond line counts) starts, and he's using Linux, which has a file-system cache. If it is a problem, do you think I should append some explanation on the -MM you see in the linked answer? I have my makefile work out dependencies for me, that makes GCC spit out the included files, one could (Python FTW) compile a graph of includes. I wont however. – Alec Teal Sep 20 '13 at 19:03
-1

The best way I know of to find undefined identifiers in a program is just to try to compile it. Depending on exactly what compiler you’re using, you might be able simply to pipe the output of GCC or Clang into grep, looking for phrases like “undeclared identifier.”

As for determining where the symbols are defined, I would recommend as a starting point looking at Ctags to parse your system headers (best managed using a Makefile) and using the resulting tags table to look up anything grep catches from GCC.

Stuart Olsen
  • 476
  • 2
  • 7
-2

The fastest way... that's not how you should think of it.

https://stackoverflow.com/a/18544093/2112028

I wrote a lovely (I'm quite proud :P) answer there talking about how linking works (with templates) and proving it works and such, understand that.

The goal of #include directives is to create a "translation unit" where every symbol is declared (even if not defined) there's an example in my answer where I simply copy and paste the prototype into a code file, rather than use include.

You ought not worry about the "fastest" way if you use something called "Header guards" (these are mentioned briefly right at the bottom, but this isn't sufficient detail) they go like this:

#ifndef __WHATEVER_H
#define __WHATEVER_H

/*Your code here*/

#endif

So now you can include "whatever.h" AS MANY times as you like. the first time IN THE TRANSLATION UNIT, will define __WHATEVER_H, so the next file that includes it (however many includes deep from the file being compiled) will be empty. as everything between the #ifndef and #endif will be gone.

Hope this helps.

Also if you have unnecessary inputs, use -Wextra and -Wall, GCC will tell you about unused functions, typedefs and so forth. you can use the pragma error push and pop things to control this. For example wxWidget's header files may contain a lot of unused things, so you push the warnings onto the stack, remove the unused warning flags, include the file, pop the warnings stack (turning them back on), less you get thousands of lines of warnings.

Community
  • 1
  • 1
Alec Teal
  • 5,770
  • 3
  • 23
  • 50
  • 5
    This doesn't really help. No part of this gives a way to tell which files to include to satisfy the dependencies of given source code, or which files you're already including aren't necessary. You can't just include *everything* and hope that's enough, and include files can interact with each other in bad ways. Also, including unnecessary header files can make dependency management a pain. – user2357112 Sep 20 '13 at 19:11
  • @user2357112 at the time two people (the other answerer and I) assumed the question to not be what it turns out he was asking. We both assumed that newbie include-OCD we all went through. Also you'll notice tat the end I suggest -Wextra and -Wall and talk about silencing the unused errors. I don't deem his actual question to be worthy of an answer; so I respect your downvote. – Alec Teal Sep 20 '13 at 19:14