9

Say you have 100s of source files (.c or .cpp) files, and you want to include some definitions, function/variable declarations in each of them. Normally in C/C++, you use header files for that purpose. But in this case you need to put #include "header.h" in each source file.

Now my question is, is there a way to include one header for all the files without putting #include "header.h" in each of the file, because it will be very tiresome to write #include "header.h" for 100s of source files.

pythonic
  • 20,589
  • 43
  • 136
  • 219

4 Answers4

15

You can use the -include flag for clang or GCC. From the man page:

-include file

Process file as if "#include "file"" appeared as the first line of the primary source file. However, the first directory searched for file is the preprocessor's working directory instead of the directory containing the main source file. If not found there, it is searched for in the remainder of the "#include "..."" search chain as normal.

If multiple -include options are given, the files are included in the order they appear on the command line.

Example:

clang -include header.h -c file1.c
clang -include header.h -c file2.c
clang -include header.h -c file3.c
clang -o app file1.o file2.o file3.o

MSVC has the /FI flag, which is similar.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
  • Yes I'm only compiling with either clang or gcc. But I can't find any example on the net. Would you mind sharing one. Thanks. – pythonic Mar 30 '12 at 15:07
3

You could solve this problem using a unix pipe

find ./ -name "*.c" -or -name "*.cpp" | xargs -n 1 sed -i '1 i #include <my_header.h>'
brice
  • 24,329
  • 7
  • 79
  • 95
1

You can't do that, although you could write a script for you to do it. A script that takes each files, and writes #include "header.h" at top. Edit: -include in gcc does this.

However, what you need is achievable in a different way through the compiler options. In gcc, with -D.

Let's say, you want the define DEBUG_LEVEL to 2 in all your source files. You can simply do this by invoking gcc like this:

gcc -DDEBUG_LEVEL=2

Note that in this case, you would need to rebuild all your project (which would have been done anyway if you had changed this definition in 1 header file to which ALL the source files depend on)

Shahbaz
  • 46,337
  • 19
  • 116
  • 182
  • Yes I know about the -D option, but it is only a replacement for #define in the header. Normally you also have other stuff in the header file, such as declarations, macros and such. – pythonic Mar 30 '12 at 15:05
0

Header files are not definitions - they are declarations.

You put as few in as possible - saves the compiler work and also inter-dependencies.

You can even reduce the number further by using forward declarations in those header files.

If you are clever you can get you IDE to help you out with filling in the gaps instead of hurting your fingers.

Ed Heal
  • 59,252
  • 17
  • 87
  • 127
  • "Header files are not definitions - they are declarations" - they're typically a mix: for things that take executable space they tend to be declarations, but for things like classes, templates, inline functions - definitions. Forward declarations are - IMHO - bad practice - you should prefer an additional forward declaration header, for example - the Standard library's `` - that way the hierarchy of includes ensures consistency and ownership is with the components declared - it ensures recompilation works when types are replaced with typdefs to particular template instantiations. – Tony Delroy Mar 30 '12 at 15:20
  • @TonyDelroy - Declarations are things that say that things will happen. As for inline functions they do not necessarily compile at all! If the `.cpp` file needs them - then the compiler just fills adds it. As to forward declarations, they save a lot of time in compilation and development time. Read the book by *Scott Myers* about the subject - it is very rare that you require to have include file for the code to compile. After all, any code using it will need to include that part. Other code not using those components of the include file can just ignore it with forward declarations. – Ed Heal Mar 30 '12 at 15:44
  • @TonyDelroy IMO it's bad practice for headers to require that the client include headers in a certain order, or for headers to include other headers, or for headers to be monolithic rather than split into logical, well designed modules. In order to avoid these things often forward declarations are necessary. And I don't see where the downside is with forward declarations. – bames53 Mar 30 '12 at 15:57
  • @bames53: Clients shouldn't need to care about order. But, maybe you should have a look at your operating system and Standard library headers to get an idea of the practical reasons they include other headers. Re headers monolithic vs well designed - that's true by implication - monolithic as you use it implies excessively inclusive and then contrasting it with well designed... :-). "don't see... downside" - did you follow what I said about templates and typedefs above? Maybe you should create a couple files and experiment. Forward declarations are fragile from a maintenance perspective. – Tony Delroy Mar 30 '12 at 16:11
  • @bames53: re templates/typedefs - can see http://stackoverflow.com/questions/4928837/why-include-a-header-and-forward-declare-the-class-contained-in-the-same-cpp-fil/4928965#4928965 for an explanation... – Tony Delroy Mar 30 '12 at 16:15
  • @TonyDelroy - They are not fragile. A class name does not change very rarely after design. Who could change what seven days are called. We have a class called Week. BTW - Self granulation is no granulation re: ref. Also you do not use forward declarations in .cpp files. – Ed Heal Mar 30 '12 at 16:19
  • @Ed: definitely it depends on their volatility and how much client code could be coupled to them... it may not matter in smaller projects or for "internal" libraries with limited exposure. They are inherently fragile, and there's no good reason to avoid forward declaration headers which address that problem, but whether you need to care is up to you. Even a `Week` class could become a `typedef` to `Week` or `Week` for some business usage.... – Tony Delroy Mar 30 '12 at 16:24
  • @TonyDelroy - I have worked in very very large projects and you decide these things before putting a line of code down. Saves on the effort of development, testing and the cost to check things out. A forward declaration in the C++ context is simple saying 'class X;' instead of '#include ' - which means that if class X changes you do not need to recompile lots of stuff. Big projects that can take a good few hours of down time for a programmer. Please just go to the book shop and look at *Scott Myers* for a good explanation. – Ed Heal Mar 30 '12 at 16:36
  • @TonyDelroy I think the problems you mention are specific to doing forward declarations incorrectly. For example you generally can't forward declare things you aren't responsible for defining. E.g. some boost libraries attempt to forward declare things in std, but this is not really allowed and breaks with libc++. Having dedicated forward declaration headers is a good idea and solves that (and I'd exempt *fwd headers from the 'no headers in headers' rule). – bames53 Mar 30 '12 at 17:37
  • @TonyDelroy Also there are tools like include-what-you-use that can analyze code and produce the minimal set of includes and forward declarations automatically, and this could be used to eliminate manually managing any of this. – bames53 Mar 30 '12 at 17:38
  • @Ed Heal: you're repeating all the obvious superficial things without addressing the reasons for a forward declaration header - which is just a small header containing "class X;" (or whatever's appropriate) anyway, but is maintained alongside the normal header and implementation. I have read Meyers, thank you. – Tony Delroy Apr 04 '12 at 03:41
  • @bames53: yes - I deliberately mentioned problems from incorrect use, and mentioned forward declaration headers as a solution. Unfortunately, minimal inclusions/forward declarations doesn't solve the problem - that extra layer is proactive decoupling. – Tony Delroy Apr 04 '12 at 03:41