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

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").


Begin the path of your #include "" directives with a sequence of one or more "../"s when:

  • you want to include a file whose collocation with the including file is fixed and
  • you are building on a POSIX system or with VC++ and
  • you wish to avoid ambiguity about which file will be included.

It is always easy to provide an example of where your code-base contains an error and where this subsequently causes a hard-to-diagnose failure. However, even if your project is fault-free, it can be abused by a third party if you rely on absolute paths to specify files that are located relative to one another.

For example, consider the following project layout:

./your_lib/include/foo/header1.h./your_lib/include/bar/header2.h./their_lib/include/bar/header2.h

How should your_lib/include/foo/header1.h include your_lib/include/bar/header2.h? Let's consider two options:

  1. #include <bar/header2.h>

    Assuming both your_lib/include and their_lib/include are cited as header search paths (e.g. using GCC's -I or -isystem options), then the choice of which header2.h will be chosen is sensitive to the order in which those two paths are searched.

  2. #include "../bar/header2.h"

    The first location in which the compiler will search is the location of your_lib/include/foo/header1.h, which is your_lib/include/foo/. It will first try your_lib/include/foo/../bar/header2.h which reduces to your_lib/include/bar/header2.h where it will find the correct file. The header search paths will not be used at all and there is little room for ambiguity.

I would strongly recommend option 2) in this case for reasons given.

In response to some arguments in other answers:

  • @andrew-grant says:

    ...it makes it very clear what namespace or module the header file belongs to.

    Maybe. But relative paths can be interpreted as "in this same module". They provide clarity in the case that there are multiple directories with the same name located in different modules.

  • @bk1e says:

    ...it will often work by accident...

    I'd argue that relative paths will only work by accident in very rare cases where the project was broken from the start and could easily be fixed. To experience such a name collision without causing a compiler error seems unlikely. A common scenario is where a dependent project's file includes one of your headers which includes another of your headers. Compiling your test suite should result in a "No such file or directory" error when compiled in isolation from that dependent project.

  • @singlenegationelimination says

    ...that's not portable and the standard does not support it.

    The ISO C standard may not specify all the details of the systems under which a program is compiled or run. That does not mean that they are unsupported, merely that the standard doesn't over-specify the platforms on which C will run. (The distinction between how "" and <> are interpreted on common modern systems likely originates in the POSIX standard.)

  • @daniel-paull says

    the ".." assumes relative location and is fragile

    Fragile how? Presumably sensitive to the collocation of the two files. Thus ".." should only (and always) be used when the author of the including file controls their location.