tags:

views:

297

answers:

9

If you have a c++ project with several source files and you hit compile, which file does the compiler start with?

I am asking cause I am having some #include-dependency issues on a library.

Compiler would be: VC2003.

+15  A: 

It should not be order-dependent. The only relevant steps are:

  1. Each compilation unit includes what it depends on, and should be compilable individually. This means, first, that each CPP file includes all the headers it depends on; and second, that each header should in turn include what it needs so that it can compile even if it is the first one to be compiled.
  2. A link step puts all the compiled object code together and builds the final binary.
Daniel Daranas
@Daniel: You could also add that each header should also include what it depends on so that it also compiles even if it is the first header included by a module.
quamrana
Thank you @quamrana, I tried to include your comment into my answer.
Daniel Daranas
The way I put it is: A source file consisting of solely a single `#include` should always compile (to a .o file) without error. I have a "hcheck" script that I use which creates a .c or .cc file which `#include`s the file specified on the command line, then tries to compile it, and deletes the temporary .c/.cc file when done.
Mike D.
Pretty neat Mike! Unfortunately I always find that template pose a problem for this, as the name-dependent symbols are not resolved before the instanciation, you sometimes realise you were missing things only then... (or that it simply does not compile because of a stupid error...)
Matthieu M.
Yes, I haven't found a way to handle templates except to create a C++ source file that pulls in the include file and instantiates a set of test template instances in a function. The test function in the source file gets declared `static` so it's not externally linked, and thus (hopefully) gets omitted by the linker so the code doesn't get bigger. Anyway, if I can't run something like `hcheck`, then I make sure that `#include "foo.h"` is the **first** non-comment, non-blank line in `foo.cc`. This has almost the same effect (exception: headers without matching source files).
Mike D.
+3  A: 

This depends on the environment. In general a "compiler" only works on a single source file at a time; you use higher-level tools to direct it and compute the proper build order.

Examples of such tools can be make, ant, CMake, SCons, Eclipse, and Visual Studio. A basic check is generally the modification date of the source code files, coupled with built-in and custom rules that define how various output files depend on the inputs.

unwind
+4  A: 

Irrelevant. Post the exact issue. The compilation order is non-deterministic and arbitrary, and must have no effect on the compilability of your project.

Alex
And in fact there might not even be a compilation order with distributed compiling. You can't say a.cpp compiled before or after b.cpp, if it happened on a different machine.
MSalters
+5  A: 

It should not matter which file it starts with, the linker resolves external references after all the files have been compiled

Anders
+1  A: 

The order the compiler compiles in shouldn't make a difference, as others have noted.

From the compiler's point of view, when you compile a file with a #include, the included file is inserted into the file being compiled at the point where the #include is, recursing as necessary.

me_and
A: 

As others have pointed out, conceptually it is not important which file it starts with. However, it can be useful to start with the most recently edited file (assuming more than one file has been edited) of with the file with the most dependencies. Some environments, such as Code::Blocks, actually allow you to give weightings to source files to give you some control over the compilation order.

anon
+1  A: 

The only "include-dependency" problem I can think of is a recursive inclusion. For which the fix normally is guarding it with #ifdef

#ifndef INCLUDED_THEFILENAME_H
#define INCLUDED_THEFILENAME_H

/* content goes here *

#endif

But you better elaborate on the issue you're having.

Michael Krelin - hacker
Note that the name __THEFILENAME_H is illegal in user-written C++ code.
anon
uhm... for macros too? Well, the name is irrelevant, anyway.
Michael Krelin - hacker
@hacker: you should still not have leading underscores, even for macros. Being uppercase is enough for a macro, its a sufficient convention for an include-guard when you have `'_H'` on the end.
quamrana
Yeah, double-underscore is reserved to the implementation no matter where it occurs (in macros, variable names, functions, anything. A typical reason is because the compiler might use these names to define its own macros). Single underscore followed by capital letter is also reserved.
jalf
Updated. Thanks for comments, standards-police ;-)
Michael Krelin - hacker
A: 

Others have already said that the order shouldn't make a difference.

What you might not have realized is that the compiler compiles every .cpp or .cc file. It does not compile header files. And typically, you only #include header files, and never .cpp files, so the order does not matter. Every .cpp file is processed in isolation. It includes a number of headers, but these are never compiled separately, and it does not typically include other .cpp files either.

jalf
it does not compile header files? what if a class has all it's code in the header file and there is no cpp-file for it?
clamp
What Jalf means (and even says, later in the paragraph) is that the compiler doesn't generally compile headers *all by themselves*. Instead, it compiles a header implicitly by virtue of compiling the .cpp file that includes it, and in that sense, a header is frequently compiled *several times*, once for each source file including it. The linker sorts out all the duplication afterward as the final build step.
Rob Kennedy
Yeah. The compiler processes "translation units". A translation unit is the result of taking one .cpp file, and copy/pasting all `#include`'s and evaluating all macros. So what the compiler sees is basically a .cpp file, with all its headers attached. But it never compiles the headers *by themselves*.
jalf
To answer your specific question, if a class has all its code in a header file, and no .cpp file, it only gets compiled if and when that header is included in another .cpp. You can try it out. Create a project in VS with only header files, or with a header you never include. The code in the header will never get compiled (so you can write complete garbage, including syntax errors
jalf
A: 

A make tool builds a directed acyclic graph of the dependencies specified in the make file. This will normally say the executable depends on a number of object files. The object files depends on source files, each source file depends on headers, and so on.

This produces essentially a multi-way tree. The tree will have the executable as its root, and typically have mostly headers as the leaf nodes (though if you're using some sort of code generator, it could also have the input file for that code generator as a leaf).

It then walks that tree working its way from the leaf nodes to the root node and building as it goes. The answers that have said "it doesn't matter" are basically pointing out that it can pick any branch of that tree to build first. It does matter, however, that when it picks a branch, it builds in the order specified for that branch.

Jerry Coffin