mirror of
https://github.com/isocpp/CppCoreGuidelines.git
synced 2025-12-18 21:24:41 +03:00
update from master
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# <a name="main"></a>C++ Core Guidelines
|
# <a name="main"></a>C++ Core Guidelines
|
||||||
|
|
||||||
February 15, 2024
|
May 11, 2024
|
||||||
|
|
||||||
Editors:
|
Editors:
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ Editors:
|
|||||||
This is a living document under continuous improvement.
|
This is a living document under continuous improvement.
|
||||||
Had it been an open-source (code) project, this would have been release 0.8.
|
Had it been an open-source (code) project, this would have been release 0.8.
|
||||||
Copying, use, modification, and creation of derivative works from this project is licensed under an MIT-style license.
|
Copying, use, modification, and creation of derivative works from this project is licensed under an MIT-style license.
|
||||||
Contributing to this project requires agreeing to a Contributor License. See the accompanying [LICENSE](LICENSE) file for details.
|
Contributing to this project requires agreeing to a Contributor License. See the accompanying [LICENSE](https://github.com/isocpp/CppCoreGuidelines/blob/master/LICENSE) file for details.
|
||||||
We make this project available to "friendly users" to use, copy, modify, and derive from, hoping for constructive input.
|
We make this project available to "friendly users" to use, copy, modify, and derive from, hoping for constructive input.
|
||||||
|
|
||||||
Comments and suggestions for improvements are most welcome.
|
Comments and suggestions for improvements are most welcome.
|
||||||
@@ -365,17 +365,17 @@ We do not limit our comment in the **Enforcement** sections to things we know ho
|
|||||||
|
|
||||||
Tools that implement these rules shall respect the following syntax to explicitly suppress a rule:
|
Tools that implement these rules shall respect the following syntax to explicitly suppress a rule:
|
||||||
|
|
||||||
[[gsl::suppress(tag)]]
|
[[gsl::suppress("tag")]]
|
||||||
|
|
||||||
and optionally with a message (following usual C++11 standard attribute syntax):
|
and optionally with a message (following usual C++11 standard attribute syntax):
|
||||||
|
|
||||||
[[gsl::suppress(tag, justification: "message")]]
|
[[gsl::suppress("tag", justification: "message")]]
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|
||||||
* `tag` is the anchor name of the item where the Enforcement rule appears (e.g., for [C.134](#Rh-public) it is "Rh-public"), the
|
* `"tag"` is a string literal with the anchor name of the item where the Enforcement rule appears (e.g., for [C.134](#Rh-public) it is "Rh-public"), the
|
||||||
name of a profile group-of-rules ("type", "bounds", or "lifetime"),
|
name of a profile group-of-rules ("type", "bounds", or "lifetime"),
|
||||||
or a specific rule in a profile ([type.4](#Pro-type-cstylecast), or [bounds.2](#Pro-bounds-arrayindex))
|
or a specific rule in a profile ([type.4](#Pro-type-cstylecast), or [bounds.2](#Pro-bounds-arrayindex)). Any text that is not one of those should be rejected.
|
||||||
|
|
||||||
* `"message"` is a string literal
|
* `"message"` is a string literal
|
||||||
|
|
||||||
@@ -1165,9 +1165,9 @@ Run a static analyzer to verify that your code follows the guidelines you want i
|
|||||||
|
|
||||||
See
|
See
|
||||||
|
|
||||||
* [Static analysis tools](???)
|
* [Static analysis tools](https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis)
|
||||||
* [Concurrency tools](#Rconc-tools)
|
* [Concurrency tools](#Rconc-tools)
|
||||||
* [Testing tools](???)
|
* [Testing tools](https://github.com/isocpp/CppCoreGuidelines/tree/master)
|
||||||
|
|
||||||
There are many other kinds of tools, such as source code repositories, build tools, etc.,
|
There are many other kinds of tools, such as source code repositories, build tools, etc.,
|
||||||
but those are beyond the scope of these guidelines.
|
but those are beyond the scope of these guidelines.
|
||||||
@@ -2306,7 +2306,7 @@ Such examples are discussed in [[Str15]](http://www.stroustrup.com/resource-mode
|
|||||||
|
|
||||||
So, we write a class
|
So, we write a class
|
||||||
|
|
||||||
class Istream { [[gsl::suppress(lifetime)]]
|
class Istream { [[gsl::suppress("lifetime")]]
|
||||||
public:
|
public:
|
||||||
enum Opt { from_line = 1 };
|
enum Opt { from_line = 1 };
|
||||||
Istream() { }
|
Istream() { }
|
||||||
@@ -3007,7 +3007,8 @@ When copying is cheap, nothing beats the simplicity and safety of copying, and f
|
|||||||
For advanced uses (only), where you really need to optimize for rvalues passed to "input-only" parameters:
|
For advanced uses (only), where you really need to optimize for rvalues passed to "input-only" parameters:
|
||||||
|
|
||||||
* If the function is going to unconditionally move from the argument, take it by `&&`. See [F.18](#Rf-consume).
|
* If the function is going to unconditionally move from the argument, take it by `&&`. See [F.18](#Rf-consume).
|
||||||
* If the function is going to keep a copy of the argument, in addition to passing by `const&` (for lvalues),
|
* If the function is going to keep a locally modifiable copy of the argument only for its own local use, taking it by value is fine
|
||||||
|
* If the function is going to keep a copy of the argument to pass to another destination (to another function, or store in a non-local location), in addition to passing by `const&` (for lvalues),
|
||||||
add an overload that passes the parameter by `&&` (for rvalues) and in the body `std::move`s it to its destination. Essentially this overloads a "will-move-from"; see [F.18](#Rf-consume).
|
add an overload that passes the parameter by `&&` (for rvalues) and in the body `std::move`s it to its destination. Essentially this overloads a "will-move-from"; see [F.18](#Rf-consume).
|
||||||
* In special cases, such as multiple "input + copy" parameters, consider using perfect forwarding. See [F.19](#Rf-forward).
|
* In special cases, such as multiple "input + copy" parameters, consider using perfect forwarding. See [F.19](#Rf-forward).
|
||||||
|
|
||||||
@@ -3663,7 +3664,7 @@ Importantly, that does not imply a transfer of ownership of the pointed-to objec
|
|||||||
##### Note
|
##### Note
|
||||||
|
|
||||||
Positions can also be transferred by iterators, indices, and references.
|
Positions can also be transferred by iterators, indices, and references.
|
||||||
A reference is often a superior alternative to a pointer [if there is no need to use `nullptr`](#Rf-ptr-ref) or [if the object referred to should not change](???).
|
A reference is often a superior alternative to a pointer [if there is no need to use `nullptr`](#Rf-ptr-ref) or [if the object referred to should not change](#S-const).
|
||||||
|
|
||||||
##### Note
|
##### Note
|
||||||
|
|
||||||
@@ -3932,11 +3933,13 @@ value) of any assignment operator.
|
|||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
|
||||||
With guaranteed copy elision, it is now almost always a pessimization to expressly use `std::move` in a return statement.
|
Returning a local variable implicitly moves it anyway.
|
||||||
|
An explicit `std::move` is always a pessimization, because it prevents Return Value Optimization (RVO),
|
||||||
|
which can eliminate the move completely.
|
||||||
|
|
||||||
##### Example, bad
|
##### Example, bad
|
||||||
|
|
||||||
S f()
|
S bad()
|
||||||
{
|
{
|
||||||
S result;
|
S result;
|
||||||
return std::move(result);
|
return std::move(result);
|
||||||
@@ -3944,9 +3947,10 @@ With guaranteed copy elision, it is now almost always a pessimization to express
|
|||||||
|
|
||||||
##### Example, good
|
##### Example, good
|
||||||
|
|
||||||
S f()
|
S good()
|
||||||
{
|
{
|
||||||
S result;
|
S result;
|
||||||
|
// Named RVO: move elision at best, move construction at worst
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4148,8 +4152,6 @@ It's confusing. Writing `[=]` in a member function appears to capture by value,
|
|||||||
// ...
|
// ...
|
||||||
|
|
||||||
auto lambda = [=] { use(i, x); }; // BAD: "looks like" copy/value capture
|
auto lambda = [=] { use(i, x); }; // BAD: "looks like" copy/value capture
|
||||||
// [&] has identical semantics and copies the this pointer under the current rules
|
|
||||||
// [=,this] and [&,this] are not much better, and confusing
|
|
||||||
|
|
||||||
x = 42;
|
x = 42;
|
||||||
lambda(); // calls use(0, 42);
|
lambda(); // calls use(0, 42);
|
||||||
@@ -4216,7 +4218,7 @@ Declaring a `...` parameter is sometimes useful for techniques that don't involv
|
|||||||
##### Enforcement
|
##### Enforcement
|
||||||
|
|
||||||
* Issue a diagnostic for using `va_list`, `va_start`, or `va_arg`.
|
* Issue a diagnostic for using `va_list`, `va_start`, or `va_arg`.
|
||||||
* Issue a diagnostic for passing an argument to a vararg parameter of a function that does not offer an overload for a more specific type in the position of the vararg. To fix: Use a different function, or `[[suppress(types)]]`.
|
* Issue a diagnostic for passing an argument to a vararg parameter of a function that does not offer an overload for a more specific type in the position of the vararg. To fix: Use a different function, or `[[suppress("type")]]`.
|
||||||
|
|
||||||
|
|
||||||
### <a name="F-nesting"></a>F.56: Avoid unnecessary condition nesting
|
### <a name="F-nesting"></a>F.56: Avoid unnecessary condition nesting
|
||||||
@@ -5094,10 +5096,6 @@ There are two general categories of classes that need a user-defined destructor:
|
|||||||
|
|
||||||
The default destructor does it better, more efficiently, and can't get it wrong.
|
The default destructor does it better, more efficiently, and can't get it wrong.
|
||||||
|
|
||||||
##### Note
|
|
||||||
|
|
||||||
If the default destructor is needed, but its generation has been suppressed (e.g., by defining a move constructor), use `=default`.
|
|
||||||
|
|
||||||
##### Enforcement
|
##### Enforcement
|
||||||
|
|
||||||
Look for likely "implicit resources", such as pointers and references. Look for classes with destructors even though all their data members have destructors.
|
Look for likely "implicit resources", such as pointers and references. Look for classes with destructors even though all their data members have destructors.
|
||||||
@@ -9539,7 +9537,7 @@ Returning a (raw) pointer imposes a lifetime management uncertainty on the calle
|
|||||||
delete p;
|
delete p;
|
||||||
}
|
}
|
||||||
|
|
||||||
In addition to suffering from the problem from [leak](#???), this adds a spurious allocation and deallocation operation, and is needlessly verbose. If Gadget is cheap to move out of a function (i.e., is small or has an efficient move operation), just return it "by value" (see ["out" return values](#Rf-out)):
|
In addition to suffering from the problem of [leak](#Rp-leak), this adds a spurious allocation and deallocation operation, and is needlessly verbose. If Gadget is cheap to move out of a function (i.e., is small or has an efficient move operation), just return it "by value" (see ["out" return values](#Rf-out)):
|
||||||
|
|
||||||
Gadget make_gadget(int n)
|
Gadget make_gadget(int n)
|
||||||
{
|
{
|
||||||
@@ -9886,6 +9884,7 @@ This is more efficient:
|
|||||||
|
|
||||||
`make_shared` gives a more concise statement of the construction.
|
`make_shared` gives a more concise statement of the construction.
|
||||||
It also gives an opportunity to eliminate a separate allocation for the reference counts, by placing the `shared_ptr`'s use counts next to its object.
|
It also gives an opportunity to eliminate a separate allocation for the reference counts, by placing the `shared_ptr`'s use counts next to its object.
|
||||||
|
It also ensures exception safety in complex expressions (in pre-C++17 code).
|
||||||
|
|
||||||
##### Example
|
##### Example
|
||||||
|
|
||||||
@@ -9905,7 +9904,7 @@ The `make_shared()` version mentions `X` only once, so it is usually shorter (as
|
|||||||
##### Reason
|
##### Reason
|
||||||
|
|
||||||
`make_unique` gives a more concise statement of the construction.
|
`make_unique` gives a more concise statement of the construction.
|
||||||
It also ensures exception safety in complex expressions.
|
It also ensures exception safety in complex expressions (in pre-C++17 code).
|
||||||
|
|
||||||
##### Example
|
##### Example
|
||||||
|
|
||||||
@@ -12680,6 +12679,10 @@ wrong results, or memory corruption.
|
|||||||
|
|
||||||
##### Note
|
##### Note
|
||||||
|
|
||||||
|
By pointer here we mean any indirection to an object, including equivalently an iterator or view.
|
||||||
|
|
||||||
|
##### Note
|
||||||
|
|
||||||
This rule is an obvious and well-known language rule, but can be hard to follow.
|
This rule is an obvious and well-known language rule, but can be hard to follow.
|
||||||
It takes good coding style, library support, and static analysis to eliminate violations without major overhead.
|
It takes good coding style, library support, and static analysis to eliminate violations without major overhead.
|
||||||
This is a major part of the discussion of [C++'s model for type- and resource-safety](#Stroustrup15).
|
This is a major part of the discussion of [C++'s model for type- and resource-safety](#Stroustrup15).
|
||||||
@@ -20993,7 +20996,7 @@ Reference sections:
|
|||||||
Libraries used have to have been approved for mission critical applications.
|
Libraries used have to have been approved for mission critical applications.
|
||||||
Any similarities to this set of guidelines are unsurprising because Bjarne Stroustrup was an author of JSF++.
|
Any similarities to this set of guidelines are unsurprising because Bjarne Stroustrup was an author of JSF++.
|
||||||
Recommended, but note its very specific focus.
|
Recommended, but note its very specific focus.
|
||||||
* [MISRA C++ 2008: Guidelines for the use of the C++ language in critical systems](https://www.misra.org.uk/Buyonline/tabid/58/Default.aspx).
|
* [MISRA C++:2023 Guidelines for the use C++17 in critical systems](https://misra.org.uk/product/misra-cpp2023/).
|
||||||
* [Using C++ in Mozilla Code](https://firefox-source-docs.mozilla.org/code-quality/coding-style/using_cxx_in_firefox_code.html).
|
* [Using C++ in Mozilla Code](https://firefox-source-docs.mozilla.org/code-quality/coding-style/using_cxx_in_firefox_code.html).
|
||||||
As the name indicates, this aims for portability across many (old) compilers.
|
As the name indicates, this aims for portability across many (old) compilers.
|
||||||
As such, it is restrictive.
|
As such, it is restrictive.
|
||||||
@@ -21155,7 +21158,7 @@ Enabling a profile is implementation defined; typically, it is set in the analys
|
|||||||
|
|
||||||
To suppress enforcement of a profile check, place a `suppress` annotation on a language contract. For example:
|
To suppress enforcement of a profile check, place a `suppress` annotation on a language contract. For example:
|
||||||
|
|
||||||
[[suppress(bounds)]] char* raw_find(char* p, int n, char x) // find x in p[0]..p[n - 1]
|
[[suppress("bounds")]] char* raw_find(char* p, int n, char x) // find x in p[0]..p[n - 1]
|
||||||
{
|
{
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
@@ -22642,7 +22645,7 @@ Prevent leaks. Leaks can lead to performance degradation, mysterious error, syst
|
|||||||
// ...
|
// ...
|
||||||
};
|
};
|
||||||
|
|
||||||
This class is a resource handle. It manages the lifetime of the `T`s. To do so, `Vector` must define or delete [the set of special operations](???) (constructors, a destructor, etc.).
|
This class is a resource handle. It manages the lifetime of the `T`s. To do so, `Vector` must define or delete [the set of special operations](#Rc-five) (constructors, a destructor, etc.).
|
||||||
|
|
||||||
##### Example
|
##### Example
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user