mirror of
https://github.com/isocpp/CppCoreGuidelines.git
synced 2024-03-22 13:30:58 +08:00
whitespaces fixes, by remark tool
This commit is contained in:
parent
033918b998
commit
c8a18317c1
|
@ -259,7 +259,6 @@ Tools that implement these rules shall respect the following syntax to explicitl
|
||||||
where "tag" is the anchor name of the item where the Enforcement rule appears (e.g., for C.134 it is "Rh-public"), the
|
where "tag" is the anchor name of the item where the Enforcement rule appears (e.g., for C.134 it is "Rh-public"), the
|
||||||
name of a profile group-of-rules ("type", "bounds", or "lifetime"), or a specific rule in a profile ("type.4", or "bounds.2").
|
name of a profile group-of-rules ("type", "bounds", or "lifetime"), or a specific rule in a profile ("type.4", or "bounds.2").
|
||||||
|
|
||||||
|
|
||||||
## <a name="SS-struct"></a>In.struct: The structure of this document
|
## <a name="SS-struct"></a>In.struct: The structure of this document
|
||||||
|
|
||||||
Each rule (guideline, suggestion) can have several parts:
|
Each rule (guideline, suggestion) can have several parts:
|
||||||
|
@ -941,8 +940,6 @@ You can't have a data race on a constant.
|
||||||
|
|
||||||
See [Con: Constants and Immutability](#S-const)
|
See [Con: Constants and Immutability](#S-const)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# <a name="S-interfaces"></a>I: Interfaces
|
# <a name="S-interfaces"></a>I: Interfaces
|
||||||
|
|
||||||
An interface is a contract between two parts of a program. Precisely stating what is expected of a supplier of a service and a user of that service is essential.
|
An interface is a contract between two parts of a program. Precisely stating what is expected of a supplier of a service and a user of that service is essential.
|
||||||
|
@ -1628,7 +1625,6 @@ But when doing so, use `string_span` from the [GSL](#GSL) to prevent range error
|
||||||
* (Simple) ((Bounds)) Warn for any expression that would rely on implicit conversion of an array type to a pointer type. Allow exception for zstring/czstring pointer types.
|
* (Simple) ((Bounds)) Warn for any expression that would rely on implicit conversion of an array type to a pointer type. Allow exception for zstring/czstring pointer types.
|
||||||
* (Simple) ((Bounds)) Warn for any arithmetic operation on an expression of pointer type that results in a value of pointer type. Allow exception for zstring/czstring pointer types.
|
* (Simple) ((Bounds)) Warn for any arithmetic operation on an expression of pointer type that results in a value of pointer type. Allow exception for zstring/czstring pointer types.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Ri-global-init"></a>I.22: Avoid complex initialization of global objects
|
### <a name="Ri-global-init"></a>I.22: Avoid complex initialization of global objects
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -2288,7 +2284,6 @@ Not possible.
|
||||||
|
|
||||||
There are a variety of ways to pass parameters to a function and to return values.
|
There are a variety of ways to pass parameters to a function and to return values.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rf-conventional"></a>F.15: Prefer simple and conventional ways of passing information
|
### <a name="Rf-conventional"></a>F.15: Prefer simple and conventional ways of passing information
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -2302,8 +2297,6 @@ The following tables summarize the advice in the following Guidelines, F.16-21.
|
||||||
|
|
||||||
![Advanced parameter passing table](./param-passing-advanced.png "Advanced parameter passing")
|
![Advanced parameter passing table](./param-passing-advanced.png "Advanced parameter passing")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rf-in"></a>F.16: For "in" parameters, pass cheaply-copied types by value and others by reference to `const`
|
### <a name="Rf-in"></a>F.16: For "in" parameters, pass cheaply-copied types by value and others by reference to `const`
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -2327,7 +2320,7 @@ For advanced uses (only), where you really need to optimize for rvalues passed t
|
||||||
|
|
||||||
* 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 copy of the argument, 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 "consume"; 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 "consume"; 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).
|
||||||
|
|
||||||
##### Example
|
##### Example
|
||||||
|
@ -2341,7 +2334,7 @@ add an overload that passes the parameter by `&&` (for rvalues) and in the body
|
||||||
Avoid "esoteric techniques" such as:
|
Avoid "esoteric techniques" such as:
|
||||||
|
|
||||||
* Passing arguments as `T&&` "for efficiency".
|
* Passing arguments as `T&&` "for efficiency".
|
||||||
Most rumors about performance advantages from passing by `&&` are false or brittle (but see [F.25](#Rf-pass-ref-move).)
|
Most rumors about performance advantages from passing by `&&` are false or brittle (but see [F.25](#Rf-pass-ref-move).)
|
||||||
* Returning `const T&` from assignments and similar operations (see [F.47](#Rf-assignment-op).)
|
* Returning `const T&` from assignments and similar operations (see [F.47](#Rf-assignment-op).)
|
||||||
|
|
||||||
##### Example
|
##### Example
|
||||||
|
@ -2368,12 +2361,12 @@ 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."
|
If you need the notion of an optional value, use a pointer, `std::optional`, or a special value used to denote "no value."
|
||||||
|
|
||||||
##### Enforcement
|
##### Enforcement
|
||||||
|
|
||||||
* (Simple) ((Foundation)) Warn when a parameter being passed by value has a size greater than `4 * sizeof(int)`.
|
* (Simple) ((Foundation)) Warn when a parameter being passed by value has a size greater than `4 * sizeof(int)`.
|
||||||
Suggest using a reference to `const` instead.
|
Suggest using a reference to `const` instead.
|
||||||
* (Simple) ((Foundation)) Warn when a `const` parameter being passed by reference has a size less than `3 * sizeof(int)`. Suggest passing by value instead.
|
* (Simple) ((Foundation)) Warn when a `const` parameter being passed by reference has a size less than `3 * sizeof(int)`. Suggest passing by value instead.
|
||||||
* (Simple) ((Foundation)) Warn when a `const` parameter being passed by reference is `move`d.
|
* (Simple) ((Foundation)) Warn when a `const` parameter being passed by reference is `move`d.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rf-inout"></a>F.17: For "in-out" parameters, pass by reference to non-`const`
|
### <a name="Rf-inout"></a>F.17: For "in-out" parameters, pass by reference to non-`const`
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -2405,10 +2398,10 @@ Here, the writer of `g()` is supplying a buffer for `f()` to fill, but `f()` sim
|
||||||
If the writer of `g()` makes an assumption about the size of `buffer` a bad logic error can happen.
|
If the writer of `g()` makes an assumption about the size of `buffer` a bad logic error can happen.
|
||||||
|
|
||||||
##### Enforcement
|
##### Enforcement
|
||||||
|
|
||||||
* (Moderate) ((Foundation)) Warn about functions with reference to non-`const` parameters that do *not* write to them.
|
* (Moderate) ((Foundation)) Warn about functions with reference to non-`const` parameters that do *not* write to them.
|
||||||
* (Simple) ((Foundation)) Warn when a non-`const` parameter being passed by reference is `move`d.
|
* (Simple) ((Foundation)) Warn when a non-`const` parameter being passed by reference is `move`d.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rf-consume"></a>F.18: For "consume" parameters, pass by `X&&` and `std::move` the parameter
|
### <a name="Rf-consume"></a>F.18: For "consume" parameters, pass by `X&&` and `std::move` the parameter
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -2434,11 +2427,11 @@ For example:
|
||||||
} // p gets destroyed
|
} // p gets destroyed
|
||||||
|
|
||||||
##### Enforcement
|
##### Enforcement
|
||||||
|
|
||||||
* Flag all `X&&` parameters (where `X` is not a template type parameter name) where the function body uses them without `std::move`.
|
* Flag all `X&&` parameters (where `X` is not a template type parameter name) where the function body uses them without `std::move`.
|
||||||
* Flag access to moved-from objects.
|
* Flag access to moved-from objects.
|
||||||
* Don't conditionally move from objects
|
* Don't conditionally move from objects
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rf-forward"></a>F.19: For "forward" parameters, pass by `TP&&` and only `std::forward` the parameter
|
### <a name="Rf-forward"></a>F.19: For "forward" parameters, pass by `TP&&` and only `std::forward` the parameter
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -2504,10 +2497,10 @@ It is not recommended to return a `const` value. Such older advice is now obsole
|
||||||
void val(int&); // Bad: Is val reading its argument
|
void val(int&); // Bad: Is val reading its argument
|
||||||
|
|
||||||
##### Enforcement
|
##### Enforcement
|
||||||
|
|
||||||
* Flag reference to non-`const` parameters that are not read before being written to and are a type that could be cheaply returned; they should be "out" return values.
|
* Flag reference to non-`const` parameters that are not read before being written to and are a type that could be cheaply returned; they should be "out" return values.
|
||||||
* Flag returning a `const` value. To fix: Remove `const` to return a non-`const` value instead.
|
* Flag returning a `const` value. To fix: Remove `const` to return a non-`const` value instead.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rf-out-multi"></a>F.21: To return multiple "out" values, prefer returning a tuple or struct
|
### <a name="Rf-out-multi"></a>F.21: To return multiple "out" values, prefer returning a tuple or struct
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -2565,7 +2558,6 @@ In some cases it may be useful to return a specific, user-defined `Value_or_erro
|
||||||
* Output parameters should be replaced by return values.
|
* 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`.
|
An output parameter is one that the function writes to, invokes a non-`const` member function, or passes on as a non-`const`.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rf-ptr"></a>F.22: Use `T*` or `owner<T*>` to designate a single object
|
### <a name="Rf-ptr"></a>F.22: Use `T*` or `owner<T*>` to designate a single object
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -2706,7 +2698,6 @@ When I call `length(s)` should I test for `s == nullptr` first? Should the imple
|
||||||
|
|
||||||
**See also**: [Support library](#S-gsl).
|
**See also**: [Support library](#S-gsl).
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rf-unique_ptr"></a>F.26: Use a `unique_ptr<T>` to transfer ownership where a pointer is needed
|
### <a name="Rf-unique_ptr"></a>F.26: Use a `unique_ptr<T>` to transfer ownership where a pointer is needed
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -2768,7 +2759,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.
|
(Not enforceable) This is a too complex pattern to reliably detect.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rf-ptr-ref"></a>F.60: Prefer `T*` over `T&` when "no argument" is a valid option
|
### <a name="Rf-ptr-ref"></a>F.60: Prefer `T*` over `T&` when "no argument" is a valid option
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -3110,7 +3100,6 @@ Functions can't capture local variables or be declared at local scope; if you ne
|
||||||
|
|
||||||
* Warn on use of a named non-generic lambda (e.g., `auto x = [](int i){ /*...*/; };`) that captures nothing and appears at global scope. Write an ordinary function instead.
|
* Warn on use of a named non-generic lambda (e.g., `auto x = [](int i){ /*...*/; };`) that captures nothing and appears at global scope. Write an ordinary function instead.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rf-default-args"></a>F.51: Where there is a choice, prefer default arguments over overloading
|
### <a name="Rf-default-args"></a>F.51: Where there is a choice, prefer default arguments over overloading
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -3145,7 +3134,6 @@ There is not a choice when a set of functions are used to do a semantically equi
|
||||||
|
|
||||||
???
|
???
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rf-reference-capture"></a>F.52: Prefer capturing by reference in lambdas that will be used locally, including passed to algorithms
|
### <a name="Rf-reference-capture"></a>F.52: Prefer capturing by reference in lambdas that will be used locally, including passed to algorithms
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -3238,7 +3226,6 @@ This is under active discussion in standardization, and may be addressed in a fu
|
||||||
|
|
||||||
* Flag any lambda capture-list that specifies a default capture and also captures `this` (whether explicitly or via default capture)
|
* Flag any lambda capture-list that specifies a default capture and also captures `this` (whether explicitly or via default capture)
|
||||||
|
|
||||||
|
|
||||||
# <a name="S-class"></a>C: Classes and Class Hierarchies
|
# <a name="S-class"></a>C: Classes and Class Hierarchies
|
||||||
|
|
||||||
A class is a user-defined type, for which a programmer can define the representation, operations, and interfaces.
|
A class is a user-defined type, for which a programmer can define the representation, operations, and interfaces.
|
||||||
|
@ -3426,7 +3413,6 @@ This is especially important for [overloaded operators](#Ro-namespace).
|
||||||
|
|
||||||
* Flag global functions taking argument types from a single namespace.
|
* Flag global functions taking argument types from a single namespace.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rc-standalone"></a>C.7: Don't define a class or enum and declare a variable of its type in the same statement
|
### <a name="Rc-standalone"></a>C.7: Don't define a class or enum and declare a variable of its type in the same statement
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -3446,7 +3432,6 @@ Mixing a type definition and the definition of another entity in the same declar
|
||||||
|
|
||||||
* Flag if the `}` of a class or enumeration definition is not followed by a `;`. The `;` is missing.
|
* Flag if the `}` of a class or enumeration definition is not followed by a `;`. The `;` is missing.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rc-class"></a>C.8: use `class` rather that `struct` if any member is non-public
|
### <a name="Rc-class"></a>C.8: use `class` rather that `struct` if any member is non-public
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -3473,7 +3458,6 @@ The data is split in different parts of the class declaration.
|
||||||
Different parts of the data has difference access.
|
Different parts of the data has difference access.
|
||||||
All of this decreases readability and complicates maintenance.
|
All of this decreases readability and complicates maintenance.
|
||||||
|
|
||||||
|
|
||||||
##### Note
|
##### Note
|
||||||
|
|
||||||
Prefer to place the interface first in a class [see](#Rl-order).
|
Prefer to place the interface first in a class [see](#Rl-order).
|
||||||
|
@ -3482,7 +3466,6 @@ Prefer to place the interface first in a class [see](#Rl-order).
|
||||||
|
|
||||||
Flag classes declared with `struct` if there is a `private` or `public` member.
|
Flag classes declared with `struct` if there is a `private` or `public` member.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rc-private"></a>C.9: minimize exposure of members
|
### <a name="Rc-private"></a>C.9: minimize exposure of members
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -4116,7 +4099,6 @@ We can imagine one case where you could want a protected virtual destructor: Whe
|
||||||
|
|
||||||
* A class with any virtual functions should have a destructor that is either public and virtual or else protected and nonvirtual.
|
* A class with any virtual functions should have a destructor that is either public and virtual or else protected and nonvirtual.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rc-dtor-fail"></a>C.36: A destructor may not fail
|
### <a name="Rc-dtor-fail"></a>C.36: A destructor may not fail
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -4444,7 +4426,6 @@ Assuming that you want initialization, an explicit default initialization can he
|
||||||
int i {}; // default initialize (to 0)
|
int i {}; // default initialize (to 0)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
##### Enforcement
|
##### Enforcement
|
||||||
|
|
||||||
* Flag classes without a default constructor
|
* Flag classes without a default constructor
|
||||||
|
@ -5554,7 +5535,6 @@ It's a standard-library requirement.
|
||||||
m[mt] = 7;
|
m[mt] = 7;
|
||||||
cout << m[My_type{ "asdfg" }] << '\n';
|
cout << m[My_type{ "asdfg" }] << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
If you have to define a `hash` specialization, try simply to let it combine standard-library `hash` specializations with `^` (xor).
|
If you have to define a `hash` specialization, try simply to let it combine standard-library `hash` specializations with `^` (xor).
|
||||||
That tends to work better than "cleverness" for non-specialists.
|
That tends to work better than "cleverness" for non-specialists.
|
||||||
|
|
||||||
|
@ -5717,6 +5697,7 @@ Interfaces should normally be composed entirely of public pure virtual functions
|
||||||
The `Derived` is `delete`d through its `Goof` interface, so its `string` is leaked.
|
The `Derived` is `delete`d through its `Goof` interface, so its `string` is leaked.
|
||||||
Give `Goof` a virtual destructor and all is well.
|
Give `Goof` a virtual destructor and all is well.
|
||||||
|
|
||||||
|
|
||||||
##### Enforcement
|
##### Enforcement
|
||||||
|
|
||||||
* Warn on any class that contains data members and also has an overridable (non-`final`) virtual function.
|
* Warn on any class that contains data members and also has an overridable (non-`final`) virtual function.
|
||||||
|
@ -5843,7 +5824,6 @@ Use `virtual` only when declaring a new virtual function. Use `override` only wh
|
||||||
* Flag overrides with neither `override` nor `final`.
|
* Flag overrides with neither `override` nor `final`.
|
||||||
* Flag function declarations that use more than one of `virtual`, `override`, and `final`.
|
* Flag function declarations that use more than one of `virtual`, `override`, and `final`.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rh-kind"></a>C.129: When designing a class hierarchy, distinguish between implementation inheritance and interface inheritance
|
### <a name="Rh-kind"></a>C.129: When designing a class hierarchy, distinguish between implementation inheritance and interface inheritance
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -5888,7 +5868,6 @@ Note that because of language rules, the covariant return type cannot be a smart
|
||||||
* Flag a class with a virtual function and a non-user-defined copy operation.
|
* Flag a class with a virtual function and a non-user-defined copy operation.
|
||||||
* Flag an assignment of base class objects (objects of a class from which another has been derived).
|
* Flag an assignment of base class objects (objects of a class from which another has been derived).
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rh-get"></a>C.131: Avoid trivial getters and setters
|
### <a name="Rh-get"></a>C.131: Avoid trivial getters and setters
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -5995,7 +5974,7 @@ Data members in category B should be `private` or `const`. This is because encap
|
||||||
Most classes are either all A or all B:
|
Most classes are either all A or all B:
|
||||||
|
|
||||||
* *All public*: If you're writing an aggregate bundle-of-variables without an invariant across those variables, then all the variables should be `public`.
|
* *All public*: If you're writing an aggregate bundle-of-variables without an invariant across those variables, then all the variables should be `public`.
|
||||||
[By convention, declare such classes `struct` rather than `class`](#Rc-struct)
|
[By convention, declare such classes `struct` rather than `class`](#Rc-struct)
|
||||||
* *All private*: If you’re writing a type that maintains an invariant, then all the non-`const` variables should be private -- it should be encapsulated.
|
* *All private*: If you’re writing a type that maintains an invariant, then all the non-`const` variables should be private -- it should be encapsulated.
|
||||||
|
|
||||||
##### Exceptions
|
##### Exceptions
|
||||||
|
@ -6006,7 +5985,6 @@ Occasionally classes will mix A and B, usually for debug reasons. An encapsulate
|
||||||
|
|
||||||
Flag any class that has non-`const` data members with different access levels.
|
Flag any class that has non-`const` data members with different access levels.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rh-mi-interface"></a>C.135: Use multiple inheritance to represent multiple distinct interfaces
|
### <a name="Rh-mi-interface"></a>C.135: Use multiple inheritance to represent multiple distinct interfaces
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -6076,7 +6054,6 @@ This a relatively rare use because implementation can often be organized into a
|
||||||
|
|
||||||
???
|
???
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rh-final"></a>C.139: Use `final` sparingly
|
### <a name="Rh-final"></a>C.139: Use `final` sparingly
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -6138,6 +6115,7 @@ However, misuses are (or at least has been) far more common.
|
||||||
|
|
||||||
Flag uses of `final`.
|
Flag uses of `final`.
|
||||||
|
|
||||||
|
|
||||||
## <a name="Rh-virtual-default-arg"></a>C.140: Do not provide different default arguments for a virtual function and an overrider
|
## <a name="Rh-virtual-default-arg"></a>C.140: Do not provide different default arguments for a virtual function and an overrider
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -6587,8 +6565,6 @@ The string allocated for `s` and assigned to `p` is destroyed before it can be u
|
||||||
|
|
||||||
Flag all conversion operators.
|
Flag all conversion operators.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <a name="Ro-custom"></a>C.165: Use `using` for customization points
|
### <a name="Ro-custom"></a>C.165: Use `using` for customization points
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -8180,10 +8156,10 @@ Do not declare a non-type with the same name as a type in the same scope. This r
|
||||||
Antique header files might declare non-types and types with the same name in the same scope.
|
Antique header files might declare non-types and types with the same name in the same scope.
|
||||||
|
|
||||||
##### Enforcement
|
##### Enforcement
|
||||||
|
|
||||||
* Check names against a list of known confusing letter and digit combinations.
|
* Check names against a list of known confusing letter and digit combinations.
|
||||||
* Flag a declaration of a variable, function, or enumerator that hides a class or enumeration declared in the same scope.
|
* Flag a declaration of a variable, function, or enumerator that hides a class or enumeration declared in the same scope.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Res-not-CAPS"></a>ES.9: Avoid `ALL_CAPS` names
|
### <a name="Res-not-CAPS"></a>ES.9: Avoid `ALL_CAPS` names
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -9193,7 +9169,6 @@ Readability.
|
||||||
|
|
||||||
Flag empty statements that are not blocks and don't contain comments.
|
Flag empty statements that are not blocks and don't contain comments.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Res-loop-counter"></a>ES.86: Avoid modifying loop control variables inside the body of raw for-loops
|
### <a name="Res-loop-counter"></a>ES.86: Avoid modifying loop control variables inside the body of raw for-loops
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -9224,8 +9199,6 @@ The loop control up front should enable correct reasoning about what is happenin
|
||||||
|
|
||||||
Flag variables that are potentially updated (have a non-const use) in both the loop control iteration-expression and the loop body.
|
Flag variables that are potentially updated (have a non-const use) in both the loop control iteration-expression and the loop body.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## ES.expr: Expressions
|
## ES.expr: Expressions
|
||||||
|
|
||||||
Expressions manipulate values.
|
Expressions manipulate values.
|
||||||
|
@ -9586,7 +9559,6 @@ Constructs that cannot overflow do not overflow (and usually run faster):
|
||||||
|
|
||||||
Look for explicit range checks and heuristically suggest alternatives.
|
Look for explicit range checks and heuristically suggest alternatives.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Res-move"></a>ES.56: Write `std::move()` only when you need to explicitly move an object to another scope
|
### <a name="Res-move"></a>ES.56: Write `std::move()` only when you need to explicitly move an object to another scope
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -9661,6 +9633,7 @@ In general, don't complicate your code without reason (??)
|
||||||
Never write `return move(local_variable);`, because the language already knows the variable is a move candidate.
|
Never write `return move(local_variable);`, because the language already knows the variable is a move candidate.
|
||||||
Writing `move` in this code won't help, and can actually be detrimental because on some compilers it interferes with RVO (the return value optimization) by creating an additional reference alias to the local variable.
|
Writing `move` in this code won't help, and can actually be detrimental because on some compilers it interferes with RVO (the return value optimization) by creating an additional reference alias to the local variable.
|
||||||
|
|
||||||
|
|
||||||
##### Example, bad
|
##### Example, bad
|
||||||
|
|
||||||
vector<int> v = std::move(make_vector()); // bad; the std::move is entirely redundant
|
vector<int> v = std::move(make_vector()); // bad; the std::move is entirely redundant
|
||||||
|
@ -9694,7 +9667,6 @@ The language already knows that a returned value is a temporary object that can
|
||||||
* Flag when `std::forward` is applied to other than a forwarding reference. (More general case of the previous rule to cover the non-moving cases.)
|
* Flag when `std::forward` is applied to other than a forwarding reference. (More general case of the previous rule to cover the non-moving cases.)
|
||||||
* Flag when an object is potentially moved from and the next operation is a `const` operation; there should first be an intervening non-`const` operation, ideally assignment, to first reset the object's value.
|
* Flag when an object is potentially moved from and the next operation is a `const` operation; there should first be an intervening non-`const` operation, ideally assignment, to first reset the object's value.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Res-new"></a>ES.60: Avoid `new` and `delete` outside resource management functions
|
### <a name="Res-new"></a>ES.60: Avoid `new` and `delete` outside resource management functions
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -9722,7 +9694,6 @@ There can be code in the `...` part that causes the `delete` never to happen.
|
||||||
|
|
||||||
Flag naked `new`s and naked `delete`s.
|
Flag naked `new`s and naked `delete`s.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Res-del"></a>ES.61: delete arrays using `delete[]` and non-arrays using `delete`
|
### <a name="Res-del"></a>ES.61: delete arrays using `delete[]` and non-arrays using `delete`
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -9958,7 +9929,6 @@ This also applies to `%`.
|
||||||
|
|
||||||
* Flag division by an integral value that could be zero
|
* Flag division by an integral value that could be zero
|
||||||
|
|
||||||
|
|
||||||
# <a name="S-performance"></a>PER: Performance
|
# <a name="S-performance"></a>PER: Performance
|
||||||
|
|
||||||
??? should this section be in the main guide???
|
??? should this section be in the main guide???
|
||||||
|
@ -10024,7 +9994,6 @@ only as impactful as a 5% improvement on B. (If you don't even know how much
|
||||||
time is spent on A or B, see <a href="#Rper-reason">PER.1</a> and <a
|
time is spent on A or B, see <a href="#Rper-reason">PER.1</a> and <a
|
||||||
href="#Rper-Knuth">PER.2</a>.)
|
href="#Rper-Knuth">PER.2</a>.)
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rper-simple"></a>PER.4: Don't assume that complicated code is necessarily faster than simple code
|
### <a name="Rper-simple"></a>PER.4: Don't assume that complicated code is necessarily faster than simple code
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -10176,6 +10145,7 @@ in a thread-friendly way.
|
||||||
|
|
||||||
The concurrency/parallelism rules in this document are designed with three goals
|
The concurrency/parallelism rules in this document are designed with three goals
|
||||||
in mind:
|
in mind:
|
||||||
|
|
||||||
* To help you write code that is amenable to being used in a threaded
|
* To help you write code that is amenable to being used in a threaded
|
||||||
environment
|
environment
|
||||||
* To show clean, safe ways to use the threading primitives offered by the
|
* To show clean, safe ways to use the threading primitives offered by the
|
||||||
|
@ -10227,6 +10197,7 @@ Note that this applies most urgently to library code and least urgently to stand
|
||||||
Although `cached_computation` works perfectly in a single-threaded environment, in a multi-threaded environment the two `static` variables result in data races and thus undefined behavior.
|
Although `cached_computation` works perfectly in a single-threaded environment, in a multi-threaded environment the two `static` variables result in data races and thus undefined behavior.
|
||||||
|
|
||||||
There are several ways that this example could be made safe for a multi-threaded environment:
|
There are several ways that this example could be made safe for a multi-threaded environment:
|
||||||
|
|
||||||
* Delegate concurrency concerns upwards to the caller.
|
* Delegate concurrency concerns upwards to the caller.
|
||||||
* Mark the `static` variables as `thread_local` (which might make caching less effective).
|
* Mark the `static` variables as `thread_local` (which might make caching less effective).
|
||||||
* Implement concurrency control, for example, protecting the two `static` variables with a `static` lock (which might reduce performance).
|
* Implement concurrency control, for example, protecting the two `static` variables with a `static` lock (which might reduce performance).
|
||||||
|
@ -10979,7 +10950,6 @@ The problem is of course that the caller now have to remember to test the return
|
||||||
|
|
||||||
Possible (only) for specific versions of this idea: e.g., test for systematic test of `valid()` after resource handle construction
|
Possible (only) for specific versions of this idea: e.g., test for systematic test of `valid()` after resource handle construction
|
||||||
|
|
||||||
|
|
||||||
## <a name="Re-no-throw-crash"></a>E.26: If you can't throw exceptions, consider failing fast
|
## <a name="Re-no-throw-crash"></a>E.26: If you can't throw exceptions, consider failing fast
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -11160,6 +11130,7 @@ A not uncommon technique is to gather cleanup at the end of the function to avoi
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (g1.valid()) cleanup(g1);
|
if (g1.valid()) cleanup(g1);
|
||||||
if (g1.valid()) cleanup(g2);
|
if (g1.valid()) cleanup(g2);
|
||||||
|
@ -11198,7 +11169,6 @@ C-stye error handling is based on the global variable `errno`, so it is essentia
|
||||||
|
|
||||||
Awkward.
|
Awkward.
|
||||||
|
|
||||||
|
|
||||||
# <a name="S-const"></a>Con: Constants and Immutability
|
# <a name="S-const"></a>Con: Constants and Immutability
|
||||||
|
|
||||||
You can't have a race condition on a constant.
|
You can't have a race condition on a constant.
|
||||||
|
@ -11270,7 +11240,6 @@ This gives a more precise statement of design intent, better readability, more e
|
||||||
|
|
||||||
* Flag a member function that is not marked `const`, but that does not perform a non-`const` operation on any member variable.
|
* Flag a member function that is not marked `const`, but that does not perform a non-`const` operation on any member variable.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rconst-ref"></a>Con.3: By default, pass pointers and references to `const`s
|
### <a name="Rconst-ref"></a>Con.3: By default, pass pointers and references to `const`s
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -12140,11 +12109,10 @@ It could even be less efficient.
|
||||||
It can be a nuisance to define all operators, but not hard.
|
It can be a nuisance to define all operators, but not hard.
|
||||||
Hopefully, C++17 will give you comparison operators by default.
|
Hopefully, C++17 will give you comparison operators by default.
|
||||||
|
|
||||||
|
|
||||||
##### Enforcement
|
##### Enforcement
|
||||||
|
|
||||||
* Flag classes the support "odd" subsets of a set of operators, e.g., `==` but not `!=` or `+` but not `-`.
|
* Flag classes the support "odd" subsets of a set of operators, e.g., `==` but not `!=` or `+` but not `-`.
|
||||||
Yes, `std::string` is "odd", but it's too late to change that.
|
Yes, `std::string` is "odd", but it's too late to change that.
|
||||||
|
|
||||||
### <a name="Rt-alias"></a>T.42: Use template aliases to simplify notation and hide implementation details
|
### <a name="Rt-alias"></a>T.42: Use template aliases to simplify notation and hide implementation details
|
||||||
|
|
||||||
|
@ -12557,7 +12525,6 @@ When `concept`s become available such alternatives can be distinguished directly
|
||||||
|
|
||||||
???
|
???
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rt-customization"></a>T.69: Inside a template, don't make an unqualified nonmember function call unless you intend it to be a customization point
|
### <a name="Rt-customization"></a>T.69: Inside a template, don't make an unqualified nonmember function call unless you intend it to be a customization point
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -13526,7 +13493,6 @@ Don't replicate the work of others.
|
||||||
Benefit from other people's work when they make improvements.
|
Benefit from other people's work when they make improvements.
|
||||||
Help other people when you make improvements.
|
Help other people when you make improvements.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rsl-sl"></a>SL.2: Prefer the standard library to other libraries
|
### <a name="Rsl-sl"></a>SL.2: Prefer the standard library to other libraries
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -13534,12 +13500,11 @@ Help other people when you make improvements.
|
||||||
More people know the standard library.
|
More people know the standard library.
|
||||||
It is more likely to be stable, well-maintained, and widely available than your own code or most other libraries.
|
It is more likely to be stable, well-maintained, and widely available than your own code or most other libraries.
|
||||||
|
|
||||||
|
|
||||||
## SL.con: Containers
|
## SL.con: Containers
|
||||||
|
|
||||||
* [SL.10: Prefer using STL `array` or `vector` instead of a C array](#Rsl-arrays)
|
* [SL.10: Prefer using STL `array` or `vector` instead of a C array](#Rsl-arrays)
|
||||||
* [SL.11: Prefer using STL `vector` by default unless you have a reason to use a different container](#Rsl-vector)
|
* [SL.11: Prefer using STL `vector` by default unless you have a reason to use a different container](#Rsl-vector)
|
||||||
???
|
???
|
||||||
|
|
||||||
### <a name="Rsl-arrays"></a>SL.10: Prefer using STL `array` or `vector` instead of a C array
|
### <a name="Rsl-arrays"></a>SL.10: Prefer using STL `array` or `vector` instead of a C array
|
||||||
|
|
||||||
|
@ -13566,7 +13531,6 @@ For a variable-length array, use `std::vector`, which additionally can change it
|
||||||
|
|
||||||
* Flag declaration of a C array inside a function or class that also declares an STL container (to avoid excessive noisy warnings on legacy non-STL code). To fix: At least change the C array to a `std::array`.
|
* Flag declaration of a C array inside a function or class that also declares an STL container (to avoid excessive noisy warnings on legacy non-STL code). To fix: At least change the C array to a `std::array`.
|
||||||
|
|
||||||
|
|
||||||
### <a name="Rsl-vector"></a>SL.11: Prefer using STL `vector` by default unless you have a reason to use a different container
|
### <a name="Rsl-vector"></a>SL.11: Prefer using STL `vector` by default unless you have a reason to use a different container
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -13591,7 +13555,6 @@ If you have a good reason to use another container, use that instead. For exampl
|
||||||
|
|
||||||
* Flag a `vector` whose size never changes after construction (such as because it's `const` or because no non-`const` functions are called on it). To fix: Use an `array` instead.
|
* Flag a `vector` whose size never changes after construction (such as because it's `const` or because no non-`const` functions are called on it). To fix: Use an `array` instead.
|
||||||
|
|
||||||
|
|
||||||
## SL.str: String
|
## SL.str: String
|
||||||
|
|
||||||
???
|
???
|
||||||
|
@ -14456,7 +14419,6 @@ The notation is that of the ISO WG21 Concepts TS (???ref???).
|
||||||
|
|
||||||
Described in [Lifetimes paper](https://github.com/isocpp/CppCoreGuidelines/blob/master/docs/Lifetimes%20I%20and%20II%20-%20v0.9.1.pdf).
|
Described in [Lifetimes paper](https://github.com/isocpp/CppCoreGuidelines/blob/master/docs/Lifetimes%20I%20and%20II%20-%20v0.9.1.pdf).
|
||||||
|
|
||||||
|
|
||||||
# <a name="S-naming"></a>NL: Naming and layout rules
|
# <a name="S-naming"></a>NL: Naming and layout rules
|
||||||
|
|
||||||
Consistent naming and layout are helpful. If for no other reason because it minimizes "my style is better than your style" arguments.
|
Consistent naming and layout are helpful. If for no other reason because it minimizes "my style is better than your style" arguments.
|
||||||
|
@ -14912,8 +14874,8 @@ These coding standards are written using [CommonMark](http://commonmark.org), an
|
||||||
|
|
||||||
We are considering the following extensions from [GitHub Flavored Markdown (GFM)](https://help.github.com/articles/github-flavored-markdown/):
|
We are considering the following extensions from [GitHub Flavored Markdown (GFM)](https://help.github.com/articles/github-flavored-markdown/):
|
||||||
|
|
||||||
- fenced code blocks (consistently using indented vs. fenced is under discussion)
|
* fenced code blocks (consistently using indented vs. fenced is under discussion)
|
||||||
- tables (none yet but we'll likely need them, and this is a GFM extension)
|
* tables (none yet but we'll likely need them, and this is a GFM extension)
|
||||||
|
|
||||||
Avoid other HTML tags and other extensions.
|
Avoid other HTML tags and other extensions.
|
||||||
|
|
||||||
|
@ -15518,7 +15480,6 @@ See the Exceptions in [F.20](#Rf-out).
|
||||||
|
|
||||||
Check for pointers and references returned from functions and see if they are assigned to resource handles (e.g., to a `unique_ptr`).
|
Check for pointers and references returned from functions and see if they are assigned to resource handles (e.g., to a `unique_ptr`).
|
||||||
|
|
||||||
|
|
||||||
### <a name="Cr-handle"></a>If a class is a resource handle, it needs a constructor, a destructor, and copy and/or move operations
|
### <a name="Cr-handle"></a>If a class is a resource handle, it needs a constructor, a destructor, and copy and/or move operations
|
||||||
|
|
||||||
##### Reason
|
##### Reason
|
||||||
|
@ -15579,7 +15540,7 @@ A relatively informal definition of terms used in the guidelines
|
||||||
* *approximation*: something (e.g., a value or a design) that is close to the perfect or ideal (value or design).
|
* *approximation*: something (e.g., a value or a design) that is close to the perfect or ideal (value or design).
|
||||||
Often an approximation is a result of trade-offs among ideals.
|
Often an approximation is a result of trade-offs among ideals.
|
||||||
* *argument*: a value passed to a function or a template, in which it is accessed through a parameter.
|
* *argument*: a value passed to a function or a template, in which it is accessed through a parameter.
|
||||||
* *array*: a homogeneous sequence of elements, usually numbered, e.g., [0:max).
|
* *array*: a homogeneous sequence of elements, usually numbered, e.g., \[0:max).
|
||||||
* *assertion*: a statement inserted into a program to state (assert) that something must always be true at this point in the program.
|
* *assertion*: a statement inserted into a program to state (assert) that something must always be true at this point in the program.
|
||||||
* *base class*: a class used as the base of a class hierarchy. Typically a base class has one or more virtual functions.
|
* *base class*: a class used as the base of a class hierarchy. Typically a base class has one or more virtual functions.
|
||||||
* *bit*: the basic unit of information in a computer. A bit can have the value 0 or the value 1.
|
* *bit*: the basic unit of information in a computer. A bit can have the value 0 or the value 1.
|
||||||
|
@ -15608,7 +15569,7 @@ A relatively informal definition of terms used in the guidelines
|
||||||
* *debugging*: the act of searching for and removing errors from a program; usually far less systematic than testing.
|
* *debugging*: the act of searching for and removing errors from a program; usually far less systematic than testing.
|
||||||
* *declaration*: the specification of a name with its type in a program.
|
* *declaration*: the specification of a name with its type in a program.
|
||||||
* *definition*: a declaration of an entity that supplies all information necessary to complete a program using the entity.
|
* *definition*: a declaration of an entity that supplies all information necessary to complete a program using the entity.
|
||||||
Simplified definition: a declaration that allocates memory.
|
Simplified definition: a declaration that allocates memory.
|
||||||
* *derived class*: a class derived from one or more base classes.
|
* *derived class*: a class derived from one or more base classes.
|
||||||
* *design*: an overall description of how a piece of software should operate to meet its specification.
|
* *design*: an overall description of how a piece of software should operate to meet its specification.
|
||||||
* *destructor*: an operation that is implicitly invoked (called) when an object is destroyed (e.g., at the end of a scope). Often, it releases resources.
|
* *destructor*: an operation that is implicitly invoked (called) when an object is destroyed (e.g., at the end of a scope). Often, it releases resources.
|
||||||
|
@ -15667,7 +15628,7 @@ Simplified definition: a declaration that allocates memory.
|
||||||
* *pseudo code*: a description of a computation written in an informal notation rather than a programming language.
|
* *pseudo code*: a description of a computation written in an informal notation rather than a programming language.
|
||||||
* *pure virtual function*: a virtual function that must be overridden in a derived class.
|
* *pure virtual function*: a virtual function that must be overridden in a derived class.
|
||||||
* *RAII*: (“Resource Acquisition Is Initialization”) a basic technique for resource management based on scopes.
|
* *RAII*: (“Resource Acquisition Is Initialization”) a basic technique for resource management based on scopes.
|
||||||
* *range*: a sequence of values that can be described by a start point and an end point. For example, [0:5) means the values 0, 1, 2, 3, and 4.
|
* *range*: a sequence of values that can be described by a start point and an end point. For example, \[0:5) means the values 0, 1, 2, 3, and 4.
|
||||||
* *regular expression*: a notation for patterns in character strings.
|
* *regular expression*: a notation for patterns in character strings.
|
||||||
* *recursion*: the act of a function calling itself; see also iteration.
|
* *recursion*: the act of a function calling itself; see also iteration.
|
||||||
* *reference*: (1) a value describing the location of a typed value in memory; (2) a variable holding such a value.
|
* *reference*: (1) a value describing the location of a typed value in memory; (2) a variable holding such a value.
|
||||||
|
@ -15702,9 +15663,6 @@ Simplified definition: a declaration that allocates memory.
|
||||||
* *virtual function*: a member function that can be overridden in a derived class.
|
* *virtual function*: a member function that can be overridden in a derived class.
|
||||||
* *word*: a basic unit of memory in a computer, often the unit used to hold an integer.
|
* *word*: a basic unit of memory in a computer, often the unit used to hold an integer.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# <a name="S-unclassified"></a>To-do: Unclassified proto-rules
|
# <a name="S-unclassified"></a>To-do: Unclassified proto-rules
|
||||||
|
|
||||||
This is our to-do list.
|
This is our to-do list.
|
||||||
|
@ -15719,7 +15677,7 @@ Alternatively, we will decide that no change is needed and delete the entry.
|
||||||
* Avoid implicit conversions
|
* Avoid implicit conversions
|
||||||
* Const member functions should be thread safe "¦ aka, but I don't really change the variable, just assign it a value the first time it’s called "¦ argh
|
* Const member functions should be thread safe "¦ aka, but I don't really change the variable, just assign it a value the first time it’s called "¦ argh
|
||||||
* Always initialize variables, use initialization lists for member variables.
|
* Always initialize variables, use initialization lists for member variables.
|
||||||
* Anyone writing a public interface which takes or returns void* should have their toes set on fire. That one has been a personal favorite of mine for a number of years. :)
|
* Anyone writing a public interface which takes or returns `void*` should have their toes set on fire. That one has been a personal favorite of mine for a number of years. :)
|
||||||
* Use `const`-ness wherever possible: member functions, variables and (yippee) `const_iterators`
|
* Use `const`-ness wherever possible: member functions, variables and (yippee) `const_iterators`
|
||||||
* Use `auto`
|
* Use `auto`
|
||||||
* `(size)` vs. `{initializers}` vs. `{Extent{size}}`
|
* `(size)` vs. `{initializers}` vs. `{Extent{size}}`
|
||||||
|
@ -15758,7 +15716,7 @@ Alternatively, we will decide that no change is needed and delete the entry.
|
||||||
* When using a `condition_variable`, always protect the condition by a mutex (atomic bool whose value is set outside of the mutex is wrong!), and use the same mutex for the condition variable itself.
|
* When using a `condition_variable`, always protect the condition by a mutex (atomic bool whose value is set outside of the mutex is wrong!), and use the same mutex for the condition variable itself.
|
||||||
* Never use `atomic_compare_exchange_strong` with `std::atomic<user-defined-struct>` (differences in padding matter, while `compare_exchange_weak` in a loop converges to stable padding)
|
* Never use `atomic_compare_exchange_strong` with `std::atomic<user-defined-struct>` (differences in padding matter, while `compare_exchange_weak` in a loop converges to stable padding)
|
||||||
* individual `shared_future` objects are not thread-safe: two threads cannot wait on the same `shared_future` object (they can wait on copies of a `shared_future` that refer to the same shared state)
|
* individual `shared_future` objects are not thread-safe: two threads cannot wait on the same `shared_future` object (they can wait on copies of a `shared_future` that refer to the same shared state)
|
||||||
* individual `shared_ptr` objects are not thread-safe: different threads can call non-`const` member functions on _different_ `shared_ptr`s that refer to the same shared object, but one thread cannot call a non-`const` member function of a `shared_ptr` object while another thread accesses that same `shared_ptr` object (if you need that, consider `atomic_shared_ptr` instead)
|
* individual `shared_ptr` objects are not thread-safe: different threads can call non-`const` member functions on *different* `shared_ptr`s that refer to the same shared object, but one thread cannot call a non-`const` member function of a `shared_ptr` object while another thread accesses that same `shared_ptr` object (if you need that, consider `atomic_shared_ptr` instead)
|
||||||
|
|
||||||
* rules for arithmetic
|
* rules for arithmetic
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user