From e47463c14a68e9de38fea7641dc5e5438f7c97e4 Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Thu, 2 Apr 2020 15:53:36 -0700 Subject: [PATCH 1/8] SF.12: Prefer the quoted form of `#include` for files relative to the including file The current guidance on SF.12 can be over-applied and devolves into "always use <>" because all compilers support adding include directories to the <> search. In this case, even the current directory may be added and so it is always possible to use <> for every header. Applying the guidance then devolves into an undesirable state where <> is always used and include"" is never used. Instead, the proposed guidance leverages and encourages the distinction between <> and "" to create an easy-to-understand rule that the original guidance hints at and that most developers already follow and understand: "" is for local headers and <> is for library and external headers. --- CppCoreGuidelines.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 93ce685ac..9de7f7577 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -18743,7 +18743,7 @@ Source file rule summary: * [SF.9: Avoid cyclic dependencies among source files](#Rs-cycles) * [SF.10: Avoid dependencies on implicitly `#include`d names](#Rs-implicit) * [SF.11: Header files should be self-contained](#Rs-contained) -* [SF.12: Prefer the angle bracket form of `#include` where you can and the quoted form everywhere else](#Rs-incform) +* [SF.12: Prefer the quoted form of `#include` for files relative to the including file and the angle bracket form everywhere else](#Rs-incform) * [SF.20: Use `namespace`s to express logical structure](#Rs-namespace) * [SF.21: Don't use an unnamed (anonymous) namespace in a header](#Rs-unnamed) @@ -19182,7 +19182,7 @@ A header should include all its dependencies. Be careful about using relative pa A test should verify that the header file itself compiles or that a cpp file which only includes the header file compiles. -### SF.12: Prefer the angle bracket form of `#include` where you can and the quoted form everywhere else +### SF.12: Prefer the quoted form of `#include` for files relative to the including file and the angle bracket form everywhere else ##### Reason @@ -19190,15 +19190,14 @@ The [standard](http://eel.is/c++draft/cpp.include) provides flexibility for comp the two forms of `#include` selected using the angle (`<>`) or quoted (`""`) syntax. Vendors take advantage of this and use different search algorithms and methods for specifying the include path. -Nevertheless, the guidance is to use the angle form when possible. This supports the fact that the -standard library headers must be included this way, is more likely to create portable code, and enables -the quoted form for other uses. For example being clear about the locality of the header relative -to files that includes it or in scenarios where the different search algorithm is required. +Nevertheless, the guidance is to use quoted form for including files that exist at a relative path to the file containing the #include statement and to use the angle bracket form everywhere else where possible. This supports being clear about the locality of the header relative to files that includes it or in scenarios where the different search algorithm is required. For example, it makes it easy to determine at a glance whether a header is being included from a local relative file versus a standard library header or an external header from another project. ##### Example - +foo.cpp: #include // From the standard library, required form - #include "helpers.h" // A project specific file, use "" form + #include //A non-local include file from an external library, use the <> form + #include "foo.h" // A local file relative to foo.cpp, use "" form + #include "utils/foo_utils.h" // A local file relative to foo.cpp, use "" form ##### Note Failing to follow this results in difficult to diagnose errors due to picking up the wrong file by incorrectly specifying the scope when it is included. From 66792e48755675913525114011ce1d51ad808824 Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Fri, 3 Apr 2020 13:01:07 -0700 Subject: [PATCH 2/8] Update wording and examples for SF.12: Prefer the quoted form of `#include` for files relative Updated wording, adjusted example, and provided a more verbose example of what can go wrong if using the wrong form. --- CppCoreGuidelines.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 9de7f7577..24578f9f4 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19190,17 +19190,17 @@ The [standard](http://eel.is/c++draft/cpp.include) provides flexibility for comp the two forms of `#include` selected using the angle (`<>`) or quoted (`""`) syntax. Vendors take advantage of this and use different search algorithms and methods for specifying the include path. -Nevertheless, the guidance is to use quoted form for including files that exist at a relative path to the file containing the #include statement and to use the angle bracket form everywhere else where possible. This supports being clear about the locality of the header relative to files that includes it or in scenarios where the different search algorithm is required. For example, it makes it easy to determine at a glance whether a header is being included from a local relative file versus a standard library header or an external header from another project. +Nevertheless, the guidance is to use the quoted form for including files that exist at a relative path to the file containing the '#include statement' and to use the angle bracket form everywhere else, where possible. This encourages being clear about the locality of the header relative to files that include it, or scenarios where the different search algorithm is required. For example, 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 an external header from another project. ##### Example -foo.cpp: - #include // From the standard library, required form - #include //A non-local include file from an external library, use the <> form - #include "foo.h" // A local file relative to foo.cpp, use "" form - #include "utils/foo_utils.h" // A local file relative to foo.cpp, use "" form + // foo.cpp: + #include // From the standard library, requires the <> form + #include // A file that is not locally relative, included from an external project; use the <> form + #include "foo.h" // A file locally relative to foo.cpp, use the "" form + #include "foo_utils/utils.h" // A file locally relative to foo.cpp, use "" form ##### Note -Failing to follow this results in difficult to diagnose errors due to picking up the wrong file by incorrectly specifying the scope when it is included. +Failing to follow this results in difficult to diagnose errors due to picking up the wrong file by incorrectly specifying the scope when it is included. For example, in a typical case where the '#include ""' search algorithm may search for a file existing at a local relative path first, then using this form to refer to a file that is not locally relative could mean that if a file ever comes into existence at the local relative path (e.g. the including file is moved to a new location), it will now be found ahead of the previous include file and the set of includes will have been changed in an unexpected way. Library creators should put their headers in a folder and have clients include those files using the relative path `#include ` From 30ef5b852460207d2fd0aca6754eb073f10574f8 Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Fri, 3 Apr 2020 14:19:18 -0700 Subject: [PATCH 3/8] update code markdown for #include --- CppCoreGuidelines.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 24578f9f4..dbf872238 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19190,7 +19190,7 @@ The [standard](http://eel.is/c++draft/cpp.include) provides flexibility for comp the two forms of `#include` selected using the angle (`<>`) or quoted (`""`) syntax. Vendors take advantage of this and use different search algorithms and methods for specifying the include path. -Nevertheless, the guidance is to use the quoted form for including files that exist at a relative path to the file containing the '#include statement' and to use the angle bracket form everywhere else, where possible. This encourages being clear about the locality of the header relative to files that include it, or scenarios where the different search algorithm is required. For example, 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 an external header from another project. +Nevertheless, the guidance is to use the quoted form for including files that exist at a relative path to the file containing the `#include` statement and to use the angle bracket form everywhere else, where possible. This encourages being clear about the locality of the header relative to files that include it, or scenarios where the different search algorithm is required. For example, 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 an external header from another project. ##### Example // foo.cpp: @@ -19200,7 +19200,7 @@ Nevertheless, the guidance is to use the quoted form for including files that ex #include "foo_utils/utils.h" // A file locally relative to foo.cpp, use "" form ##### Note -Failing to follow this results in difficult to diagnose errors due to picking up the wrong file by incorrectly specifying the scope when it is included. For example, in a typical case where the '#include ""' search algorithm may search for a file existing at a local relative path first, then using this form to refer to a file that is not locally relative could mean that if a file ever comes into existence at the local relative path (e.g. the including file is moved to a new location), it will now be found ahead of the previous include file and the set of includes will have been changed in an unexpected way. +Failing to follow this results in difficult to diagnose errors due to picking up the wrong file by incorrectly specifying the scope when it is included. For example, in a typical case where the `#include ""` search algorithm may search for a file existing at a local relative path first, then using this form to refer to a file that is not locally relative could mean that if a file ever comes into existence at the local relative path (e.g. the including file is moved to a new location), it will now be found ahead of the previous include file and the set of includes will have been changed in an unexpected way. Library creators should put their headers in a folder and have clients include those files using the relative path `#include ` From 426ac8747d392696aca9ac62ce4959d98a4cf5a2 Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Wed, 22 Apr 2020 12:30:50 -0700 Subject: [PATCH 4/8] updated wording around use of <> for projects make it more clear that using <> for external projects is just a typical example (and not the only use case for <> outside of standard headers) --- CppCoreGuidelines.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 97e900cfb..2afd8066a 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19189,12 +19189,13 @@ The [standard](http://eel.is/c++draft/cpp.include) provides flexibility for comp the two forms of `#include` selected using the angle (`<>`) or quoted (`""`) syntax. Vendors take advantage of this and use different search algorithms and methods for specifying the include path. -Nevertheless, the guidance is to use the quoted form for including files that exist at a relative path to the file containing the `#include` statement and to use the angle bracket form everywhere else, where possible. This encourages being clear about the locality of the header relative to files that include it, or scenarios where the different search algorithm is required. For example, 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 an external header from another project. +Nevertheless, the guidance is to use the quoted form for including files that exist at a relative path to the file containing the `#include` statement and to use the angle bracket form everywhere else, where possible. This encourages being clear about the locality of the header relative to files that include it, or scenarios where the different search algorithm is required. 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 project or a common set of includes). ##### Example + // foo.cpp: #include // From the standard library, requires the <> form - #include // A file that is not locally relative, included from an external project; use the <> form + #include // A file that is not locally relative, included from another project; use the <> form #include "foo.h" // A file locally relative to foo.cpp, use the "" form #include "foo_utils/utils.h" // A file locally relative to foo.cpp, use "" form From 4e61010c271fc32b5cca8eb643c9a9adce664fd1 Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Thu, 23 Apr 2020 02:57:54 -0700 Subject: [PATCH 5/8] keep wording more consistent .... if a bit more monotonous, but that's ok. --- CppCoreGuidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 2afd8066a..0959852da 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19197,7 +19197,7 @@ Nevertheless, the guidance is to use the quoted form for including files that ex #include // From the standard library, requires the <> form #include // A file that is not locally relative, included from another project; use the <> form #include "foo.h" // A file locally relative to foo.cpp, use the "" form - #include "foo_utils/utils.h" // A file locally relative to foo.cpp, use "" form + #include "foo_utils/utils.h" // A file locally relative to foo.cpp, use the "" form ##### Note From f4c80921d6ae07315e90de25a18120a01a8ded63 Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Sat, 25 Apr 2020 13:01:25 -0700 Subject: [PATCH 6/8] Update CppCoreGuidelines.md --- CppCoreGuidelines.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 0959852da..91eae8934 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19189,13 +19189,13 @@ The [standard](http://eel.is/c++draft/cpp.include) provides flexibility for comp the two forms of `#include` selected using the angle (`<>`) or quoted (`""`) syntax. Vendors take advantage of this and use different search algorithms and methods for specifying the include path. -Nevertheless, the guidance is to use the quoted form for including files that exist at a relative path to the file containing the `#include` statement and to use the angle bracket form everywhere else, where possible. This encourages being clear about the locality of the header relative to files that include it, or scenarios where the different search algorithm is required. 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 project or a common set of includes). +Nevertheless, the guidance is to use the quoted form for including files that exist at a relative path to the file containing the `#include` statement and to use the angle bracket form everywhere else, where possible. This encourages being clear about the locality of the header relative to files that include it, or scenarios where the different search algorithm is required. 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). ##### Example // foo.cpp: #include // From the standard library, requires the <> form - #include // A file that is not locally relative, included from another project; use the <> form + #include // A file that is not locally relative, included from another library; use the <> form #include "foo.h" // A file locally relative to foo.cpp, use the "" form #include "foo_utils/utils.h" // A file locally relative to foo.cpp, use the "" form From f458adae1f9dcb1d6b1aaa2c15d6f4abde184bc1 Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Thu, 23 Jul 2020 14:41:33 -0700 Subject: [PATCH 7/8] Update CppCoreGuidelines.md explicitly note that "file" refers to as it exists in the location of it being authored/modified. this is to address any confusion about #including "bar.h" from foo.h based on whether bar.h is relative to foo.h at the time and location foo.h is being modified (e.g. under mylib/foo.h) versus at the time/location from which foo.h is installed to the system and included by the user (e.g. from /usr/include). --- CppCoreGuidelines.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 91eae8934..a9aa18628 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19189,7 +19189,8 @@ The [standard](http://eel.is/c++draft/cpp.include) provides flexibility for comp the two forms of `#include` selected using the angle (`<>`) or quoted (`""`) syntax. Vendors take advantage of this and use different search algorithms and methods for specifying the include path. -Nevertheless, the guidance is to use the quoted form for including files that exist at a relative path to the file containing the `#include` statement and to use the angle bracket form everywhere else, where possible. This encourages being clear about the locality of the header relative to files that include it, or scenarios where the different search algorithm is required. 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). +Nevertheless, the guidance is to use the quoted form for including files that exist at a relative path to the file containing the `#include` statement and to use the angle bracket form everywhere else, where possible. This encourages being clear about the locality of the file relative to files that include it, or scenarios where the different search algorithm is required. 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). +Note that this guidance applies to the including file as it exists in the location where it is typically authored/edited, and not any other location to which it may subsequently be copied or installed or otherwise made available to the implementation. ##### Example From 94d6123c9a9e7e6bf825ccaf36f7dd1f1244bad7 Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Thu, 23 Jul 2020 17:24:42 -0700 Subject: [PATCH 8/8] relative path should be from within the same component ... files that exist at a relative path to the file containing the `#include` statement (from within the same component or project) --- CppCoreGuidelines.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index a9aa18628..94a053d11 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19189,16 +19189,15 @@ The [standard](http://eel.is/c++draft/cpp.include) provides flexibility for comp the two forms of `#include` selected using the angle (`<>`) or quoted (`""`) syntax. Vendors take advantage of this and use different search algorithms and methods for specifying the include path. -Nevertheless, the guidance is to use the quoted form for including files that exist at a relative path to the file containing the `#include` statement and to use the angle bracket form everywhere else, where possible. This encourages being clear about the locality of the file relative to files that include it, or scenarios where the different search algorithm is required. 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). -Note that this guidance applies to the including file as it exists in the location where it is typically authored/edited, and not any other location to which it may subsequently be copied or installed or otherwise made available to the implementation. +Nevertheless, the guidance is to use the quoted form for including files that exist at a relative path to the file containing the `#include` statement (from within the same component or project) and to use the angle bracket form everywhere else, where possible. This encourages being clear about the locality of the file relative to files that include it, or scenarios where the different search algorithm is required. 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). ##### Example // foo.cpp: #include // From the standard library, requires the <> form #include // A file that is not locally relative, included from another library; use the <> form - #include "foo.h" // A file locally relative to foo.cpp, use the "" form - #include "foo_utils/utils.h" // A file locally relative to foo.cpp, use the "" form + #include "foo.h" // A file locally relative to foo.cpp in the same project, use the "" form + #include "foo_utils/utils.h" // A file locally relative to foo.cpp in the same project, use the "" form ##### Note