What are the benefits of a relative path such as "../include/header.h" for a header?

I prefer the path syntax as it makes it very clear what namespace or module the header file belongs to.

#include "Physics/Solver.h"

Is very self-describing without requiring every module to prefix their name to header files.

I almost never use the ".." syntax though, instead I have my project includes specify the correct base locations.


The problem with #include "../include/header.h" is that it will often work by accident, and then a seemingly unrelated change will make it stop working later.

For example, consider the following source layout:

./include/header.h
./lib/library.c
./lib/feature/feature.c

And let's say that you're running the compiler with an include path of -I. -I./lib. What happens?

  • ./lib/library.c can do #include "../include/header.h", which makes sense.
  • ./lib/feature/feature.c can also do #include "../include/header.h", even though it doesn't make sense. This is because the compiler will try the #include directive relative to the location of the current file, and if that fails, it will try the #include directive relative to each -I entry in the #include path.

Furthermore, if you later remove -I./lib from the #include path, then you break ./lib/feature/feature.c.

I find something like the following to be preferable:

./projectname/include/header.h
./projectname/lib/library.c
./projectname/lib/feature/feature.c

I wouldn't add any include path entries other than -I., and then both library.c and feature.c would use #include "projectname/include/header.h". Assuming that "projectname" is likely to be unique, this should not result in name collisions or ambiguities in most circumstances. You can also use the include path and/or make's VPATH feature to split the project's physical layout across multiple directories if absolutely necessary (to accommodate platform-specific auto-generated code, for instance; this is something that really breaks down when you use #include "../../somefile.h").


IANALL, but I don't think you should be putting ..'s in actual C or C++ source files, because that's not portable and the standard does not support it. This is similar to using \'s on Windows. Only do it if your compiler can't work with any other method.

Tags:

C

Header

Include