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.