C[++]: Normalizing include syntax ("" vs <>)

Stephan Bergmann sbergman at redhat.com
Thu Nov 2 09:15:56 UTC 2017

On 10/06/2017 11:26 AM, Kaganski Mike wrote:
> Here I propose an updated rule to follow in the use of includes in the
> project's code:
> 1. Use *only* <> syntax for any include that resides in include paths
> explicitly defined in the module's mk file (gb_Library_set_include),
> global includes ($INCLUDE), e.g., /include, and system headers (<vector>
> or <Windows.h>) - these are interface headers.
> As all implementations agree to use both implementation include places
> and -I-defined places as search paths for <> syntax, this will likely
> not allow inconsistency problems (and is actually what is used now in
> most of the code).
> 2. Use *only* <> syntax for includes inside headers that reside in such
> places (e.g., no header in /include should include other headers using
> "" itself). This is aimed to prevent cases where some header placed in
> the current source's directory would conflict with an include referred
> from a global interface header.
> 3. *Always* use "" syntax *only* for includes that refer to headers
> placed next to the current source in the same directory (or
> subdirectories), i.e. that would be found using the "." entry of -I
> switch. These are implementation headers. This applies to both includes
> in c[xx] files as well as in h[xx] residing in directories like
> /sw/source/core/access (as opposed to those in /sw/inc).

What happened to get implemented now with the help of a rewriting 
loplugin:includeform is slightly different:

   Use the "..." form if and only if the included file is found next to
   the including file.  Otherwise, use the <...> form.

More technically:  Use the "p" form if and only if the "perceived" 
(i.e., as potentially modified through #line directives) absolute path 
of the including file is p'/f (with f being just a file name, not a 
multi-segment path), and the absolute path of an included file can be 
written as p'/p (with p potentially being a multi-segment relative path).

This is independent of whether the including file is the translation 
unit's main source file (".cxx") or itself an include file (".hxx"). 
And that is how the actual rules differ from rule (2) of the three 
original rules quoted above.  (Though in practice include files in the 
include/ tree will still reference other include files with the <...> 
form, even with the modified rules, due to the hierarchical structure of 
the include/ tree and the way such includes are written with relative 
paths, include/foo/bar.hxx using #include <foo/baz.hxx> notation, not 
#include "baz.hxx".)

The original rule (2) rationale "to prevent cases where some header 
placed in the current source's directory would conflict with an include 
referred from a global interface header" should be a non-issue anyway: 
For the "..." form, all compilers first search next to the including 
file itself, so actually including a file that can be found that way is 
safe from any clashes.  MSVC then additionally searches next to each 
file in the "include stack", so that sloppily written Windows-only code 
could accidentally use "..." when it should actually use <...>, but 
loplugin:includeform will then find that blunder (when at least I 
occasionally run the Clang plugins on Windows).

(The reason to use the potentially #line-modified, "perceived" pathname 
is more of an aesthetic than a technical nature; it would look odd to 
reference include files next to a flex or bison source file with <...> 
instead of "...", different from how those would be written for a 
genuine C/C++ source file.)

The loplugin:includeform remains enabled (in a non-rewriting mode), so 
Jenkins may occasionally block your Gerrit changes for a wrong choice of 
"..." vs. <...> include form.  However, as the now-redundant -I switches 
that make the current translation unit's path be searched for the <...> 
form are removed, chances that such wrong choices would not already be 
found by a local (non-Clang-plugins) build should be low.

More information about the LibreOffice mailing list