From 697a78b4f405e76f0f76854525bca315ebbcfc2e Mon Sep 17 00:00:00 2001 From: Sergey Zubkov Date: Thu, 5 May 2022 16:19:56 -0400 Subject: [PATCH 01/14] NL: rules-> suggestsions (closes #1906) --- CppCoreGuidelines.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 5d2104d1d..4a978b31d 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -52,7 +52,7 @@ Supporting sections: * [RF: References](#S-references) * [Pro: Profiles](#S-profile) * [GSL: Guidelines support library](#S-gsl) -* [NL: Naming and layout rules](#S-naming) +* [NL: Naming and layout suggestions](#S-naming) * [FAQ: Answers to frequently asked questions](#S-faq) * [Appendix A: Libraries](#S-libraries) * [Appendix B: Modernizing code](#S-modernizing) @@ -445,7 +445,7 @@ Supporting sections: * [RF: References](#S-references) * [Pro: Profiles](#S-profile) * [GSL: Guidelines support library](#S-gsl) -* [NL: Naming and layout rules](#S-naming) +* [NL: Naming and layout suggestions](#S-naming) * [FAQ: Answers to frequently asked questions](#S-faq) * [Appendix A: Libraries](#S-libraries) * [Appendix B: Modernizing code](#S-modernizing) @@ -21238,7 +21238,7 @@ Many of them are very similar to what became part of the ISO C++ standard in C++ * `Unique_pointer` // A type that matches `Pointer`, is movable, and is not copyable * `Shared_pointer` // A type that matches `Pointer`, and is copyable -# NL: Naming and layout rules +# NL: Naming and layout suggestions (if you don't already have one) Consistent naming and layout are helpful. If for no other reason because it minimizes "my style is better than your style" arguments. From e30543d06aea5e162f8af60d8fcdd13ddd734e44 Mon Sep 17 00:00:00 2001 From: Sergey Zubkov Date: Sat, 7 May 2022 23:02:44 -0400 Subject: [PATCH 02/14] NL dropping parenthesized bit, per commit comment --- CppCoreGuidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 4a978b31d..ffdebe84c 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -21238,7 +21238,7 @@ Many of them are very similar to what became part of the ISO C++ standard in C++ * `Unique_pointer` // A type that matches `Pointer`, is movable, and is not copyable * `Shared_pointer` // A type that matches `Pointer`, and is copyable -# NL: Naming and layout suggestions (if you don't already have one) +# NL: Naming and layout suggestions Consistent naming and layout are helpful. If for no other reason because it minimizes "my style is better than your style" arguments. From ddef6cdbaeba9ec70e58e52eeb54635c0f3f0804 Mon Sep 17 00:00:00 2001 From: Markus Hofbauer Date: Thu, 19 May 2022 23:05:04 +0200 Subject: [PATCH 03/14] Move F.60 to align with TOC (#1914) --- CppCoreGuidelines.md | 66 ++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index ffdebe84c..375cb08bf 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -3230,6 +3230,39 @@ Another example, use a specific type along the lines of `variant` * Output parameters should be replaced by return values. An output parameter is one that the function writes to, invokes a non-`const` member function, or passes on as a non-`const`. +### F.60: Prefer `T*` over `T&` when "no argument" is a valid option + +##### Reason + +A pointer (`T*`) can be a `nullptr` and a reference (`T&`) cannot, there is no valid "null reference". +Sometimes having `nullptr` as an alternative to indicated "no object" is useful, but if it is not, a reference is notationally simpler and might yield better code. + +##### Example + + string zstring_to_string(zstring p) // zstring is a char*; that is a C-style string + { + if (!p) return string{}; // p might be nullptr; remember to check + return string{p}; + } + + void print(const vector& r) + { + // r refers to a vector; no check needed + } + +##### Note + +It is possible, but not valid C++ to construct a reference that is essentially a `nullptr` (e.g., `T* p = nullptr; T& r = *p;`). +That error is very uncommon. + +##### Note + +If you prefer the pointer notation (`->` and/or `*` vs. `.`), `not_null` provides the same guarantee as `T&`. + +##### Enforcement + +* Flag ??? + ### F.22: Use `T*` or `owner` to designate a single object ##### Reason @@ -3468,39 +3501,6 @@ Have a single object own the shared object (e.g. a scoped object) and destroy th (Not enforceable) This is a too complex pattern to reliably detect. -### F.60: Prefer `T*` over `T&` when "no argument" is a valid option - -##### Reason - -A pointer (`T*`) can be a `nullptr` and a reference (`T&`) cannot, there is no valid "null reference". -Sometimes having `nullptr` as an alternative to indicated "no object" is useful, but if it is not, a reference is notationally simpler and might yield better code. - -##### Example - - string zstring_to_string(zstring p) // zstring is a char*; that is a C-style string - { - if (!p) return string{}; // p might be nullptr; remember to check - return string{p}; - } - - void print(const vector& r) - { - // r refers to a vector; no check needed - } - -##### Note - -It is possible, but not valid C++ to construct a reference that is essentially a `nullptr` (e.g., `T* p = nullptr; T& r = *p;`). -That error is very uncommon. - -##### Note - -If you prefer the pointer notation (`->` and/or `*` vs. `.`), `not_null` provides the same guarantee as `T&`. - -##### Enforcement - -* Flag ??? - ### F.42: Return a `T*` to indicate a position (only) ##### Reason From a534f4a168eb42c3efdb732f22ca3cc686f8a2d7 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Mon, 13 Jun 2022 18:09:54 +0200 Subject: [PATCH 04/14] F.16 ("in" parameters): Move Matrix example to F.20 (return values) (#1922) The `Matrix` example and the notes about assignment appear off-topic in rule F.16, as F.16 is specifically about "in" parameters. With help from Sergey Zubkov. --- CppCoreGuidelines.md | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 375cb08bf..0b884cc80 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -2927,31 +2927,11 @@ For advanced uses (only), where you really need to optimize for rvalues passed t void sink(unique_ptr); // input only, and moves ownership of the widget -Avoid "esoteric techniques" such as: - -* Passing arguments as `T&&` "for efficiency". - Most rumors about performance advantages from passing by `&&` are false or brittle (but see [F.18](#Rf-consume) and [F.19](#Rf-forward)). -* Returning `const T&` from assignments and similar operations (see [F.47](#Rf-assignment-op).) - -##### Example - -Assuming that `Matrix` has move operations (possibly by keeping its elements in a `std::vector`): - - Matrix operator+(const Matrix& a, const Matrix& b) - { - Matrix res; - // ... fill res with the sum ... - return res; - } - - Matrix x = m1 + m2; // move constructor - - y = m3 + m3; // move assignment +Avoid "esoteric techniques" such as passing arguments as `T&&` "for efficiency". +Most rumors about performance advantages from passing by `&&` are false or brittle (but see [F.18](#Rf-consume) and [F.19](#Rf-forward)). ##### Notes -The return value optimization doesn't handle the assignment case, but the move assignment does. - A reference can be assumed to refer to a valid object (language rule). There is no (legitimate) "null reference." If you need the notion of an optional value, use a pointer, `std::optional`, or a special value used to denote "no value." @@ -3104,6 +3084,26 @@ The argument against is that it prevents (very frequent) use of move semantics. * If a type is expensive to move (e.g., `array`), consider allocating it on the free store and return a handle (e.g., `unique_ptr`), or passing it in a reference to non-`const` target object to fill (to be used as an out-parameter). * To reuse an object that carries capacity (e.g., `std::string`, `std::vector`) across multiple calls to the function in an inner loop: [treat it as an in/out parameter and pass by reference](#Rf-out-multi). +##### Example + +Assuming that `Matrix` has move operations (possibly by keeping its elements in a `std::vector`): + + Matrix operator+(const Matrix& a, const Matrix& b) + { + Matrix res; + // ... fill res with the sum ... + return res; + } + + Matrix x = m1 + m2; // move constructor + + y = m3 + m3; // move assignment + + +##### Note + +The return value optimization doesn't handle the assignment case, but the move assignment does. + ##### Example struct Package { // exceptional case: expensive-to-move object From 9ead2c44b4bedf212aa4add84afead043110a73b Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Mon, 13 Jun 2022 18:11:50 +0200 Subject: [PATCH 05/14] SL.io.50 (Avoid `endl`): Mention string streams (#1920) Explicitly mentioned string streams as `endl` insertions into string streams do actually occur in the wild. With help from Sergey Zubkov. --- CppCoreGuidelines.md | 8 ++++++++ scripts/hunspell/isocpp.dic | 1 + 2 files changed, 9 insertions(+) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 0b884cc80..a252c9583 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -20308,6 +20308,14 @@ For writing to a file, there is rarely a need to `flush`. ##### Note +For string streams (specifically `ostringstream`), the insertion of an `endl` is entirely equivalent +to the insertion of a `'\n'` character, but also in this case, `endl` might be significantly slower. + +`endl` does *not* take care of producing a platform specific end-of-line sequence (like "\r\n" on +Windows). So for a string stream, `s << endl` just inserts a *single* character, `'\n'`. + +##### Note + Apart from the (occasionally important) issue of performance, the choice between `'\n'` and `endl` is almost completely aesthetic. diff --git a/scripts/hunspell/isocpp.dic b/scripts/hunspell/isocpp.dic index ef45e4ecd..e9d90e50f 100644 --- a/scripts/hunspell/isocpp.dic +++ b/scripts/hunspell/isocpp.dic @@ -389,6 +389,7 @@ optimizable O'Reilly org ostream +ostringstream overabstract overconstrain overconstrained From d5907d6dd505844237249f37c0a6f7cc02c9ab56 Mon Sep 17 00:00:00 2001 From: Herb Sutter Date: Mon, 13 Jun 2022 13:14:54 -0700 Subject: [PATCH 06/14] Extended E.16 to include copy ctor for exception type, closes #1921 --- CppCoreGuidelines.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index a252c9583..1510e3484 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -1,6 +1,6 @@ # C++ Core Guidelines -January 3, 2022 +June 13, 2022 Editors: @@ -15629,7 +15629,7 @@ Error-handling rule summary: * [E.13: Never throw while being the direct owner of an object](#Re-never-throw) * [E.14: Use purpose-designed user-defined types as exceptions (not built-in types)](#Re-exception-types) * [E.15: Throw by value, catch exceptions from a hierarchy by reference](#Re-exception-ref) -* [E.16: Destructors, deallocation, and `swap` must never fail](#Re-never-fail) +* [E.16: Destructors, deallocation, `swap`, and exception type copy/move construction must never fail](#Re-never-fail) * [E.17: Don't try to catch every exception in every function](#Re-not-always) * [E.18: Minimize the use of explicit `try`/`catch`](#Re-catch) * [E.19: Use a `final_action` object to express cleanup if no suitable resource handle is available](#Re-finally) @@ -16096,11 +16096,11 @@ To rethrow a caught exception use `throw;` not `throw e;`. Using `throw e;` woul * Flag catching by value of a type that has a virtual function. * Flag throwing raw pointers. -### E.16: Destructors, deallocation, and `swap` must never fail +### E.16: Destructors, deallocation, `swap`, and exception type copy/move construction must never fail ##### Reason -We don't know how to write reliable programs if a destructor, a swap, or a memory deallocation fails; that is, if it exits by an exception or simply doesn't perform its required action. +We don't know how to write reliable programs if a destructor, a swap, a memory deallocation, or attempting to copy/move-construct an exception object fails; that is, if it exits by an exception or simply doesn't perform its required action. ##### Example, don't @@ -16129,14 +16129,17 @@ The standard library assumes that destructors, deallocation functions (e.g., `op ##### Note -Deallocation functions, including `operator delete`, must be `noexcept`. `swap` functions must be `noexcept`. -Most destructors are implicitly `noexcept` by default. -Also, [make move operations `noexcept`](#Rc-move-noexcept). +- Deallocation functions, including `operator delete`, must be `noexcept`. +- `swap` functions must be `noexcept`. +- Most destructors are implicitly `noexcept` by default. +- Also, [make move operations `noexcept`](#Rc-move-noexcept). +- If writing a type intended to be used as an exception type, ensure its copy constructor is not `noexcept`. In general we cannot mechanically enforce this, because we do not know whether a type is intended to be used as an exception type. +- Try not to `throw` a type whose copy constructor is not `noexcept`. In general we cannot mechanically enforce this, because even `throw std::string(...)` could throw but does not in practice. ##### Enforcement -Catch destructors, deallocation operations, and `swap`s that `throw`. -Catch such operations that are not `noexcept`. +- Catch destructors, deallocation operations, and `swap`s that `throw`. +- Catch such operations that are not `noexcept`. **See also**: [discussion](#Sd-never-fail) From 81dfb4814d06fcb9c4e1d859f4288544869dc5d0 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Wed, 15 Jun 2022 16:01:28 +0200 Subject: [PATCH 07/14] Fix GitHub Actions build warnings, Marker style should be `*` (#1925) --- CppCoreGuidelines.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 1510e3484..26c6a9e7f 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -16129,17 +16129,17 @@ The standard library assumes that destructors, deallocation functions (e.g., `op ##### Note -- Deallocation functions, including `operator delete`, must be `noexcept`. -- `swap` functions must be `noexcept`. -- Most destructors are implicitly `noexcept` by default. -- Also, [make move operations `noexcept`](#Rc-move-noexcept). -- If writing a type intended to be used as an exception type, ensure its copy constructor is not `noexcept`. In general we cannot mechanically enforce this, because we do not know whether a type is intended to be used as an exception type. -- Try not to `throw` a type whose copy constructor is not `noexcept`. In general we cannot mechanically enforce this, because even `throw std::string(...)` could throw but does not in practice. +* Deallocation functions, including `operator delete`, must be `noexcept`. +* `swap` functions must be `noexcept`. +* Most destructors are implicitly `noexcept` by default. +* Also, [make move operations `noexcept`](#Rc-move-noexcept). +* If writing a type intended to be used as an exception type, ensure its copy constructor is not `noexcept`. In general we cannot mechanically enforce this, because we do not know whether a type is intended to be used as an exception type. +* Try not to `throw` a type whose copy constructor is not `noexcept`. In general we cannot mechanically enforce this, because even `throw std::string(...)` could throw but does not in practice. ##### Enforcement -- Catch destructors, deallocation operations, and `swap`s that `throw`. -- Catch such operations that are not `noexcept`. +* Catch destructors, deallocation operations, and `swap`s that `throw`. +* Catch such operations that are not `noexcept`. **See also**: [discussion](#Sd-never-fail) From 6d018fcf5f5643588b8f6d72908af41ad686d277 Mon Sep 17 00:00:00 2001 From: Francisco Moretti Date: Sat, 25 Jun 2022 15:53:25 -0300 Subject: [PATCH 08/14] C.166: Use markdown format and document title for link (#1929) --- CppCoreGuidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 26c6a9e7f..78619dd63 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -8440,7 +8440,7 @@ Many parts of the C++ semantics assume its default meaning. If you "mess with" operator `&` be sure that its definition has matching meanings for `->`, `[]`, `*`, and `.` on the result type. Note that operator `.` currently cannot be overloaded so a perfect system is impossible. -We hope to remedy that: . +We hope to remedy that: [Operator Dot (R2)](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4477.pdf). Note that `std::addressof()` always yields a built-in pointer. ##### Enforcement From fde9ee5de1780dc054270864429ebc949c075284 Mon Sep 17 00:00:00 2001 From: Sven van Haastregt Date: Thu, 7 Jul 2022 14:04:59 +0100 Subject: [PATCH 09/14] C.9: Improve an inline link (#1933) Avoid ending the sentence with a dangling "see". --- CppCoreGuidelines.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 78619dd63..d5cd868ed 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -4477,7 +4477,7 @@ For example, a derived class might be allowed to skip a run-time check because i ##### Note -Prefer the order `public` members before `protected` members before `private` members [see](#Rl-order). +Prefer the order `public` members before `protected` members before `private` members; see [NL.16](#Rl-order). ##### Enforcement From 42c4cc6a754a11120004820c8d292e8c7581b1bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Szeder?= Date: Wed, 13 Jul 2022 18:05:36 +0200 Subject: [PATCH 10/14] E.19: clarify that `finally` is from the GSL (#1936) When I stumbled upon E.19 "Use a `final_action` object to express cleanup if no suitable resource handle is available" I was hopeful that this `final_action`/`finally()` thing is from the STL, but, alas, it isn't. Make it clear that `finally` is a GSL construct. --- CppCoreGuidelines.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index d5cd868ed..eaab74d58 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -16216,14 +16216,14 @@ Better: ##### Reason -`finally` is less verbose and harder to get wrong than `try`/`catch`. +`finally` from the [GSL](#S-gsl) is less verbose and harder to get wrong than `try`/`catch`. ##### Example void f(int n) { void* p = malloc(n); - auto _ = finally([p] { free(p); }); + auto _ = gsl::finally([p] { free(p); }); // ... } From f2e9b5c2ac36af08b9dcc25813012cee8ec6544d Mon Sep 17 00:00:00 2001 From: Ankur Satle Date: Wed, 13 Jul 2022 21:36:56 +0530 Subject: [PATCH 11/14] Issue #1931: C++20 wasn't included in "modern C++" (#1932) * Issue #1931 - Include C++20 as 'modern C++' * "modern C++" means C++11 and newer --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 15c66d6f3..b26629661 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Many of the guidelines make use of the header-only Guidelines Support Library. O ## Background and scope -The aim of the guidelines is to help people to use modern C++ effectively. By "modern C++" we mean C++11, C++14, and C++17. In other +The aim of the guidelines is to help people to use modern C++ effectively. By "modern C++" we mean C++11 and newer. In other words, what would you like your code to look like in 5 years' time, given that you can start now? In 10 years' time? The guidelines are focused on relatively higher-level issues, such as interfaces, resource management, memory management, and concurrency. Such From cbf455407e969240bdda70240bdb6206f690e6ee Mon Sep 17 00:00:00 2001 From: bgloyer <36457894+bgloyer@users.noreply.github.com> Date: Wed, 13 Jul 2022 09:23:14 -0700 Subject: [PATCH 12/14] Clean up and add example for C.32 - raw pointers (#1909) * Update CppCoreGuidelines.md * Update CppCoreGuidelines.md * Update isocpp.dic * use snake casing * sake case naming * C 32 comments (#3) * F.16 ("in" parameters): Move Matrix example to F.20 (return values) (#1922) The `Matrix` example and the notes about assignment appear off-topic in rule F.16, as F.16 is specifically about "in" parameters. With help from Sergey Zubkov. * SL.io.50 (Avoid `endl`): Mention string streams (#1920) Explicitly mentioned string streams as `endl` insertions into string streams do actually occur in the wild. With help from Sergey Zubkov. * Extended E.16 to include copy ctor for exception type, closes #1921 * Fix GitHub Actions build warnings, Marker style should be `*` (#1925) * restored reference * Added references to note Co-authored-by: Niels Dekker Co-authored-by: Herb Sutter Co-authored-by: Niels Dekker Co-authored-by: Herb Sutter --- CppCoreGuidelines.md | 13 ++++++++++--- scripts/hunspell/isocpp.dic | 3 +++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index eaab74d58..fceee695c 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -4993,12 +4993,19 @@ There is a lot of code that is non-specific about ownership. ##### Example - ??? + class legacy_class + { + foo* m_owning; + bar* m_observer; + } + +The only way to determine ownership may be to dig through the code to look for +allocations. If a pointer or reference is owning, document it as owning. ##### Note -If the `T*` or `T&` is owning, mark it `owning`. If the `T*` is not owning, consider marking it `ptr`. -This will aid documentation and analysis. +Ownership should be clear in new code (and refactored legacy code) according to [R.20](#Rr-owner) for owned +pointers and [R.3](#Rr-ptr) for non-owned pointers. References should never own [R.4](#Rr-ref). ##### Enforcement diff --git a/scripts/hunspell/isocpp.dic b/scripts/hunspell/isocpp.dic index e9d90e50f..0b3520d19 100644 --- a/scripts/hunspell/isocpp.dic +++ b/scripts/hunspell/isocpp.dic @@ -286,6 +286,7 @@ Lakos Lakos96 Lavavej LCSD05 +legacy_class lifecycle *life-time linearization @@ -301,6 +302,8 @@ lvalues m1 m2 m3 +m_owning; +m_observer; macros2 malloc mallocfree From 2b05a48a050664cb1039b3efb958057a91b36f82 Mon Sep 17 00:00:00 2001 From: Sergey Zubkov Date: Wed, 13 Jul 2022 12:36:52 -0400 Subject: [PATCH 13/14] F.1 drop invalid line closes #1928 --- CppCoreGuidelines.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index fceee695c..233a6e74c 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -2432,7 +2432,6 @@ Naming that lambda breaks up the expression into its logical parts and provides auto lessT = [](T x, T y) { return x.rank() < y.rank() && x.value() < y.value(); }; sort(a, b, lessT); - find_if(a, b, lessT); The shortest code is not always the best for performance or maintainability. From 4b8b2819b98c45b5ad22092a432da72bbf00bc79 Mon Sep 17 00:00:00 2001 From: Sergey Zubkov Date: Wed, 13 Jul 2022 14:19:39 -0400 Subject: [PATCH 14/14] C.32: amend merged PR per call notes. It overlaps R.3 quite a bit --- CppCoreGuidelines.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 233a6e74c..9b9d12eb5 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -1,6 +1,6 @@ # C++ Core Guidelines -June 13, 2022 +July 13, 2022 Editors: @@ -4994,17 +4994,16 @@ There is a lot of code that is non-specific about ownership. class legacy_class { - foo* m_owning; - bar* m_observer; + foo* m_owning; // Bad: change to unique_ptr or owner + bar* m_observer; // OK: keep } -The only way to determine ownership may be to dig through the code to look for -allocations. If a pointer or reference is owning, document it as owning. +The only way to determine ownership may be code analysis. ##### Note -Ownership should be clear in new code (and refactored legacy code) according to [R.20](#Rr-owner) for owned -pointers and [R.3](#Rr-ptr) for non-owned pointers. References should never own [R.4](#Rr-ref). +Ownership should be clear in new code (and refactored legacy code) according to [R.20](#Rr-owner) for owning +pointers and [R.3](#Rr-ptr) for non-owning pointers. References should never own [R.4](#Rr-ref). ##### Enforcement