From 70b4692181f1d2a6c760ba54a64b0309402f8dcc Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Tue, 10 Oct 2023 16:05:01 -0700 Subject: [PATCH 01/10] SF.13 Use portable header identifiers in `#include` statements add a new rule governing how to compose portable header path identifiers such that they respect proper casing (, not ) and portable path separators ('/') --- CppCoreGuidelines.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index f96aa6311..df88198f1 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19208,6 +19208,7 @@ Source file rule summary: * [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 quoted form of `#include` for files relative to the including file and the angle bracket form everywhere else](#Rs-incform) +* [SF.13: Use portable header identifiers in `#include` statements](#Rs-include-casing) * [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) @@ -19631,6 +19632,32 @@ Library creators should put their headers in a folder and have clients include t A test should identify whether headers referenced via `""` could be referenced with `<>`. +### SF.13: Use portable header identifiers in `#include` statements + +##### Reason + +The [standard](http://eel.is/c++draft/cpp.include) does not specifiy how compilers locate headers from a unique identifier in a '#include' directive, nor does it specify what constitutes uniqueness for an identifier. For example, whether the implementation considers the identifiers to be case-sensitive, or whether the identifiers are file system paths to a header file, and if so, how a hierarchical file system path is delimited. + +To maximize the portability of `#include` directives across compilers, guidance is to: +- use case-sensitivity for the header identifier, matching how the header is defined by the standard, specification, implementation, header file, etc. +- when the header identifier is a hierarchical file system path, use forward-slash '/' to delimit path components as this is the most widely-accepted, portable path-delimiting character. + +##### Example + + // good examples + #include + #include + #include "utils/utils.h" + + // bad examples + // #include // the standard library defines a header identified as , not + // #include // the standard library defines a header identified as , not + // #include "utils\utils.h" // may not work if '\u' is interpreted as an escape sequence, or on a system where '\' is not a valid path separator + +##### Enforcement + +It is only possible to enforce on implementations where header identifiers are case-sensitive and which only support '/' as a file path delimiter. + ### SF.20: Use `namespace`s to express logical structure ##### Reason From 6ee25a4c7757076895a9e68049b5d73b2ee288ef Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Tue, 10 Oct 2023 16:08:50 -0700 Subject: [PATCH 02/10] anchor --- CppCoreGuidelines.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index df88198f1..564956546 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19208,7 +19208,7 @@ Source file rule summary: * [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 quoted form of `#include` for files relative to the including file and the angle bracket form everywhere else](#Rs-incform) -* [SF.13: Use portable header identifiers in `#include` statements](#Rs-include-casing) +* [SF.13: Use portable header identifiers in `#include` statements](#Rs-portable-headerid) * [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) @@ -19632,7 +19632,7 @@ Library creators should put their headers in a folder and have clients include t A test should identify whether headers referenced via `""` could be referenced with `<>`. -### SF.13: Use portable header identifiers in `#include` statements +### SF.13: Use portable header identifiers in `#include` statements ##### Reason From 9f38cb2f22f9a1e78cc36ff4e74c0698fb6b91f6 Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Tue, 10 Oct 2023 16:23:38 -0700 Subject: [PATCH 03/10] fix typos --- CppCoreGuidelines.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 564956546..27f362776 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19208,7 +19208,7 @@ Source file rule summary: * [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 quoted form of `#include` for files relative to the including file and the angle bracket form everywhere else](#Rs-incform) -* [SF.13: Use portable header identifiers in `#include` statements](#Rs-portable-headerid) +* [SF.13: Use portable header identifiers in `#include` statements](#Rs-portable-header-id) * [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) @@ -19632,15 +19632,16 @@ Library creators should put their headers in a folder and have clients include t A test should identify whether headers referenced via `""` could be referenced with `<>`. -### SF.13: Use portable header identifiers in `#include` statements +### SF.13: Use portable header identifiers in `#include` statements ##### Reason -The [standard](http://eel.is/c++draft/cpp.include) does not specifiy how compilers locate headers from a unique identifier in a '#include' directive, nor does it specify what constitutes uniqueness for an identifier. For example, whether the implementation considers the identifiers to be case-sensitive, or whether the identifiers are file system paths to a header file, and if so, how a hierarchical file system path is delimited. +The [standard](http://eel.is/c++draft/cpp.include) does not specify how compilers locate headers from a unique identifier in a `#include` directive, nor does it specify what constitutes uniqueness for an identifier. For example, whether the implementation considers the identifiers to be case-sensitive, or whether the identifiers are file system paths to a header file, and if so, how a hierarchical file system path is delimited. To maximize the portability of `#include` directives across compilers, guidance is to: -- use case-sensitivity for the header identifier, matching how the header is defined by the standard, specification, implementation, header file, etc. -- when the header identifier is a hierarchical file system path, use forward-slash '/' to delimit path components as this is the most widely-accepted, portable path-delimiting character. + +* use case-sensitivity for the header identifier, matching how the header is defined by the standard, specification, implementation, header file, etc. +* when the header identifier is a hierarchical file system path, use forward-slash `/` to delimit path components as this is the most widely-accepted, portable path-delimiting character. ##### Example @@ -19652,11 +19653,11 @@ To maximize the portability of `#include` directives across compilers, guidance // bad examples // #include // the standard library defines a header identified as , not // #include // the standard library defines a header identified as , not - // #include "utils\utils.h" // may not work if '\u' is interpreted as an escape sequence, or on a system where '\' is not a valid path separator + // #include "utils\utils.h" // may not work if `\u` is interpreted as an escape sequence, or on a system where `\` is not a valid path separator ##### Enforcement -It is only possible to enforce on implementations where header identifiers are case-sensitive and which only support '/' as a file path delimiter. +It is only possible to enforce on implementations where header identifiers are case-sensitive and which only support `/` as a file path delimiter. ### SF.20: Use `namespace`s to express logical structure From 518c0d102f34e898c07d7463729da4bc5d0f75ee Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Tue, 10 Oct 2023 16:54:53 -0700 Subject: [PATCH 04/10] fix warnings --- CppCoreGuidelines.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 27f362776..fb9ce9fd3 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19648,12 +19648,13 @@ To maximize the portability of `#include` directives across compilers, guidance // good examples #include #include - #include "utils/utils.h" + #include "foo_utils/utils.h" // bad examples // #include // the standard library defines a header identified as , not // #include // the standard library defines a header identified as , not - // #include "utils\utils.h" // may not work if `\u` is interpreted as an escape sequence, or on a system where `\` is not a valid path separator + // #include "foo_utils\utils.h" // may not work if `\u` is interpreted as an escape sequence, or on a system where `\` is not a valid path separator + // #include "Foo_Utils/Utils.H" // the header file as it exists on the file system is "foo_utils/utils.h" ##### Enforcement From 7cef9a1052634bd658fba7ed76ec8ae1696bfadc Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Tue, 10 Oct 2023 16:57:44 -0700 Subject: [PATCH 05/10] nit --- CppCoreGuidelines.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index fb9ce9fd3..f9b242a11 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19651,10 +19651,10 @@ To maximize the portability of `#include` directives across compilers, guidance #include "foo_utils/utils.h" // bad examples - // #include // the standard library defines a header identified as , not - // #include // the standard library defines a header identified as , not - // #include "foo_utils\utils.h" // may not work if `\u` is interpreted as an escape sequence, or on a system where `\` is not a valid path separator - // #include "Foo_Utils/Utils.H" // the header file as it exists on the file system is "foo_utils/utils.h" + #include // the standard library defines a header identified as , not + #include // the standard library defines a header identified as , not + #include "foo_utils\utils.h" // may not work if `\u` is interpreted as an escape sequence, or on a system where `\` is not a valid path separator + #include "Foo_Utils/Utils.H" // the header file as it exists on the file system is "foo_utils/utils.h" ##### Enforcement From 163e9528ef1ab6a343aaee577306daf569f909ac Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Tue, 10 Oct 2023 17:07:12 -0700 Subject: [PATCH 06/10] nit --- CppCoreGuidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index f9b242a11..098764cf5 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19654,7 +19654,7 @@ To maximize the portability of `#include` directives across compilers, guidance #include // the standard library defines a header identified as , not #include // the standard library defines a header identified as , not #include "foo_utils\utils.h" // may not work if `\u` is interpreted as an escape sequence, or on a system where `\` is not a valid path separator - #include "Foo_Utils/Utils.H" // the header file as it exists on the file system is "foo_utils/utils.h" + #include "Foo_Utils/Utils.H" // the header file exists on the file system as `"foo_utils/utils.h"` ##### Enforcement From 3a21fc00eb0eeac80a9827b57e6e486ed111e814 Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Tue, 10 Oct 2023 17:10:35 -0700 Subject: [PATCH 07/10] nit --- CppCoreGuidelines.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 098764cf5..57f4e9d09 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19653,8 +19653,8 @@ To maximize the portability of `#include` directives across compilers, guidance // bad examples #include // the standard library defines a header identified as , not #include // the standard library defines a header identified as , not - #include "foo_utils\utils.h" // may not work if `\u` is interpreted as an escape sequence, or on a system where `\` is not a valid path separator - #include "Foo_Utils/Utils.H" // the header file exists on the file system as `"foo_utils/utils.h"` + #include "Foo_Utils/Utils.H" // the header file exists on the file system as "foo_utils/utils.h" + #include "foo_utils\utils.h" // may not work if `\u` is interpreted as an escape sequence, or on a system where '\' is not a valid path separator ##### Enforcement From e10f7831bd510fa4e26bd86c87b5253728a8cc99 Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Tue, 10 Oct 2023 22:13:12 -0700 Subject: [PATCH 08/10] normalize on 'util' --- CppCoreGuidelines.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 57f4e9d09..c4ecf19a6 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19619,7 +19619,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 library; 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 + #include "util/util.h" // A file locally relative to foo.cpp in the same project, use the "" form #include // A file in the same project located via a search path, use the <> form ##### Note @@ -19648,13 +19648,13 @@ To maximize the portability of `#include` directives across compilers, guidance // good examples #include #include - #include "foo_utils/utils.h" + #include "util/util.h" // bad examples - #include // the standard library defines a header identified as , not - #include // the standard library defines a header identified as , not - #include "Foo_Utils/Utils.H" // the header file exists on the file system as "foo_utils/utils.h" - #include "foo_utils\utils.h" // may not work if `\u` is interpreted as an escape sequence, or on a system where '\' is not a valid path separator + #include // the standard library defines a header identified as , not + #include // the standard library defines a header identified as , not + #include "Util/Util.H" // the header file exists on the file system as "util/util.h" + #include "util\util.h" // may not work if the implementation interprets `\u` as an escape sequence, or where '\' is not a valid path separator ##### Enforcement From c8b8d9e916f4604b813af3710d158f86f3680508 Mon Sep 17 00:00:00 2001 From: apenn-msft <62863214+apenn-msft@users.noreply.github.com> Date: Tue, 10 Oct 2023 22:34:46 -0700 Subject: [PATCH 09/10] clean up wording --- CppCoreGuidelines.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index c4ecf19a6..38ab89a25 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19636,12 +19636,12 @@ A test should identify whether headers referenced via `""` could be referenced w ##### Reason -The [standard](http://eel.is/c++draft/cpp.include) does not specify how compilers locate headers from a unique identifier in a `#include` directive, nor does it specify what constitutes uniqueness for an identifier. For example, whether the implementation considers the identifiers to be case-sensitive, or whether the identifiers are file system paths to a header file, and if so, how a hierarchical file system path is delimited. +The [standard](http://eel.is/c++draft/cpp.include) does not specify how compilers uniquely locate headers from an identifier in an `#include` directive, nor does it specify what constitutes uniqueness. For example, whether the implementation considers the identifiers to be case-sensitive, or whether the identifiers are file system paths to a header file, and if so, how a hierarchical file system path is delimited. To maximize the portability of `#include` directives across compilers, guidance is to: -* use case-sensitivity for the header identifier, matching how the header is defined by the standard, specification, implementation, header file, etc. -* when the header identifier is a hierarchical file system path, use forward-slash `/` to delimit path components as this is the most widely-accepted, portable path-delimiting character. +* use case-sensitivity for the header identifier, matching how the header is defined by the standard, specification, implementation, or file that provides the header. +* when the header identifier is a hierarchical file path, use forward-slash `/` to delimit path components as this is the most widely-accepted path-delimiting character. ##### Example From e6e6a010085d62ca819e9b77135ff5eb9a772631 Mon Sep 17 00:00:00 2001 From: Herb Sutter Date: Thu, 12 Oct 2023 12:31:12 -0700 Subject: [PATCH 10/10] Update CppCoreGuidelines.md --- CppCoreGuidelines.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 38ab89a25..1f84394c9 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -19651,10 +19651,10 @@ To maximize the portability of `#include` directives across compilers, guidance #include "util/util.h" // bad examples - #include // the standard library defines a header identified as , not - #include // the standard library defines a header identified as , not - #include "Util/Util.H" // the header file exists on the file system as "util/util.h" - #include "util\util.h" // may not work if the implementation interprets `\u` as an escape sequence, or where '\' is not a valid path separator + #include // bad: the standard library defines a header identified as , not + #include // bad: the standard library defines a header identified as , not + #include "Util/Util.H" // bad: the header file exists on the file system as "util/util.h" + #include "util\util.h" // bad: may not work if the implementation interprets `\u` as an escape sequence, or where '\' is not a valid path separator ##### Enforcement