SF.12 is ambiguous when a library uses a unique include subfolder
(See also this SO question.)
Rule SF.12 says we should
use the quoted form for including files that exist at a relative path ...
because:
This encourages being clear about the locality of the file...
and
It makes it easy to understand at a glance whether a header is being included from a local relative file versus a standard library header or a header from the alternate search path (e.g. a header from another library or a common set of includes).
but - what about the case where locality is clear, because the library uses a unique include subfolder? e.g. #include <my_lib/some_file.hpp>? In fact, in this case, another, more specific part of SF.12 seems to apply:
Library creators should put their headers in a folder and have clients include those files using the relative path
#include <some_library/common.h>
as a library's include file is also a "client" of the library's (other) include files.
It is also worth mentioning that the Boost libraries seem to prefer angle-brackets for files known to be accessible via relative paths.
So, I suggest one of two things:
- Amend the general rule to exclude the case of a library-specific include subfolder/prefix.
- Clarify that, within a library's include files, one should prefer quoted include paths
I'm a bit partial to (1.) - it's my personal style so far - but don't have a strong opinion.
This seems to be, in essence, what https://github.com/isocpp/CppCoreGuidelines/pull/1596#issuecomment-1113901271 talks about
@cubbimew : Definitely very related to this issue. It seems like we (or I should say, you) need to decide what you think about "a user of compiler supplanting <foo/utils.h>. If that's treated as "don't care what happens, good luck with that" - then there's no sense guarding against it. If this needs guarding against, then option (2.) in my opening comment is the appropriate one.
It is also worth mentioning that libstdc++ 12 and Boost seem to prefer angle-brackets for files known to be accessible via relative paths.
For libstdc++ this is at least partly because there isn't a single directory containing all the libstdc++ headers, and it's just simpler to use a consistent style. For example, <bits/locale_classes.h> and <bits/ctype_base.h> are not in the same directory. The former could be found from <locale> using "..." and a relative path, but the latter is found via a different predefined include path known to the compiler. Using <...> consistently means not having to care about which ones are local and which ones are not. But I wouldn't try to draw too many conclusions from libstdc++, since its headers are split across four directories that are all baked in to the compiler. It's not a typical scenario.
I'm saying the compiler's own headers are not representative of "normal" code.
@jwakely : Fair enough, dropped that as an example. I wonder which large (set of) libraries I should refer to other than Boost though.
Editors call: We should just say what we mean, which is to use quotes if the #include'd file is in the same component as the #include-ing file, and angles if not.
@hsutter : So, a clarification then (option (2.) in my opening comment)?