Skip to content

Commit a62e5e6

Browse files
author
Colin Robertson
authored
Merge pull request #3065 from MicrosoftDocs/FromPublicMasterBranch
Confirm merge from FromPublicMasterBranch to master to sync with https://github.com/MicrosoftDocs/cpp-docs (branch master)
2 parents 195f02a + bfaea0b commit a62e5e6

File tree

17 files changed

+118
-41
lines changed

17 files changed

+118
-41
lines changed

docs/code-quality/c26415.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ ms.assetid: 4165f70a-78ae-4a03-b256-c4bd74b02d09
1111
"Smart pointer parameter is used only to access contained pointer. Use T* or T& instead."
1212

1313
**C++ Core Guidelines**:
14-
R.30: Take smart pointers as parameters only to explicitly express lifetime semantics
14+
[R.30](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#r30-take-smart-pointers-as-parameters-only-to-explicitly-express-lifetime-semantics): Take smart pointers as parameters only to explicitly express lifetime semantics
1515

1616
Using a smart pointer type to pass data to a function indicates that the target function needs to manage the lifetime of the contained object. However, if the function only uses the smart pointer to access the contained object and never actually calls any code that may lead to its deallocation (that is, never affect its lifetime), there is usually no need to complicate the interface with smart pointers. A plain pointer or reference to the contained object is preferred.
1717

docs/code-quality/c26416.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ ms.assetid: f158207b-45cf-44cf-8e4b-b5b75b56ea0e
1111
> Shared pointer parameter is passed by rvalue reference. Pass by value instead.
1212
1313
**C++ Core Guidelines**:
14-
R.34: Take a shared_ptr\<widget> parameter to express that a function is part owner
14+
[R.34](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#r34-take-a-shared_ptrwidget-parameter-to-express-that-a-function-is-part-owner): Take a shared_ptr\<widget> parameter to express that a function is part owner
1515

1616
Passing a shared pointer by rvalue reference is usually unnecessary. Unless it is an implementation of move semantics for a shared pointer type itself, shared pointer objects can be safely passed by value. Using rvalue reference may be also an indication that unique pointer is more appropriate since it clearly transfers unique ownership from caller to callee.
1717

docs/code-quality/c26417.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ ms.assetid: 0e09fcc6-f9eb-4404-b51e-5815705c6afb
1111
> Shared pointer parameter is passed by reference and not reset or reassigned. Use T* or T& instead.
1212
1313
**C++ Core Guidelines**:
14-
R.35: Take a shared_ptr\<widget>& parameter to express that a function might reseat the shared pointer
14+
[R.35](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#r35-take-a-shared_ptrwidget-parameter-to-express-that-a-function-might-reseat-the-shared-pointer): Take a shared_ptr\<widget>& parameter to express that a function might reseat the shared pointer
1515

1616
Passing shared pointers by reference may be useful in scenarios where callee code updates target of the smart pointer object and its caller expects to see such update. Using a reference solely to reduce costs of passing a shared pointer is questionable. If callee code only accesses target object and never manages its lifetime, it is safer to pass raw pointer or reference, rather than to expose resource management details.
1717

docs/code-quality/c26418.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ ms.assetid: d2c84a40-8a5d-4018-92c2-6498cdd9b541
1111
> Shared pointer parameter is not copied or moved. Use T* or T& instead.
1212
1313
**C++ Core Guidelines**:
14-
R.36: Take a const shared_ptr\<widget>& parameter to express that it might retain a reference count to the object
14+
[R.36](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#r36-take-a-const-shared_ptrwidget-parameter-to-express-that-it-might-retain-a-reference-count-to-the-object-): Take a const shared_ptr\<widget>& parameter to express that it might retain a reference count to the object
1515

1616
If shared pointer parameter is passed by value or reference to a constant object it is expected that function will take control of its target object’s lifetime without affecting of the caller. The code should either copy or move the shared pointer parameter to another shared pointer object or pass it further to other code by invoking functions which accept shared pointers. If this is not the case, then plain pointer or reference may be feasible.
1717

docs/code-quality/c26426.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ ms.assetid: 6fb5f6d2-b097-47f8-8b49-f2fd4e9bef0e
1111
"Global initializer calls a non-constexpr function."
1212

1313
**C++ Core Guidelines**:
14-
I.22: Avoid complex initialization of global objects
14+
[I.22](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#i22-avoid-complex-initialization-of-global-objects): Avoid complex initialization of global objects
1515

1616
The order of execution of initializers for global objects may be inconsistent or undefined. This can lead to issues that are hard to reproduce and investigate. To avoid such problems, global initializers should not depend on external code that's executed at run time and can potentially depend on data that's not yet initialized. This rule flags cases where global objects call functions to obtain their initial values.
1717

docs/code-quality/c26429.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ ms.assetid: 4e1c74d5-7307-436c-927b-f74ae863282c
1212
"Symbol is never tested for nullness, it can be marked as gsl::not_null."
1313

1414
**C++ Core Guidelines**:
15-
F.23: Use a not_null\<T> to indicate that "null" is not a valid value
15+
[F.23](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f23-use-a-not_nullt-to-indicate-that-null-is-not-a-valid-value): Use a not_null\<T> to indicate that "null" is not a valid value
1616

1717
It is a common practice to use asserts to enforce assumptions about validity of pointer values. The problem with asserts is that they do not expose assumptions through the interface (e.g. in return types or parameters). Asserts are also harder to maintain and keep in sync with other code changes. The recommendation is to use gsl::not_null from the Guidelines Support Library as a marker of resources which should never have null value. The rule USE_NOTNULL helps to identify places that omit checks for nullness and hence can be updated to use gsl::not_null.
1818

docs/code-quality/c26430.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ ms.assetid: 3dca2626-8102-4eed-8ff3-73eb3d5c328c
1212
"Symbol is not tested for nullness on all paths."
1313

1414
**C++ Core Guidelines**:
15-
F.23: Use a not_null\<T> to indicate that "null" is not a valid value
15+
[F.23](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f23-use-a-not_nullt-to-indicate-that-null-is-not-a-valid-value): Use a not_null\<T> to indicate that "null" is not a valid value
1616

1717
If code ever checks nullness of pointer variables it should do this consistently and validate pointers on all paths. Sometimes overaggressive checking for nullness is still better than possibility of a hard crash in one of the complicated branches. Ideally such code should be refactored to be less complex (by splitting into multiple functions) and to rely on markers like gsl::not_null (see Guidelines Support Library) to isolate parts of algorithm that can make safe assumption about valid pointer values. The rule TEST_ON_ALL_PATHS helps to find places where nullness checks are either inconsistent (hence assumptions may require review) or actual bugs where potential null value can bypass nullness check in some of the code paths.
1818

docs/code-quality/c26431.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ ms.assetid: 40be6032-c8de-49ab-8e43-e8eedc0ca0ba
1212
"The type of expression is already gsl::not_null. Do not test it for nullness."
1313

1414
**C++ Core Guidelines**:
15-
F.23: Use a not_null\<T> to indicate that "null" is not a valid value
15+
[F.23](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#f23-use-a-not_nullt-to-indicate-that-null-is-not-a-valid-value): Use a not_null\<T> to indicate that "null" is not a valid value
1616

1717
The marker type gsl::not_null from Guidelines Support Library is used to clearly indicate values that are never null pointers. It causes a hard failure if such assumption is not held at run time. So, obviously, there is no need to check for nullness if expression evaluates to a result of type gsl::not_null.
1818

docs/code-quality/c26432.md

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
title: C26432
3+
description: "Microsoft C++ Code Analysis warning C26432 for the C++ Core Guidelines case C.21."
34
ms.date: 11/15/2017
45
ms.topic: "conceptual"
56
f1_keywords: ["C26432"]
@@ -8,21 +9,50 @@ ms.assetid: f587b05a-5c69-4176-baa6-fcb79d228b24
89
---
910
# C26432 DEFINE_OR_DELETE_SPECIAL_OPS
1011

11-
"If you define or delete any default operation in the type, define or delete them all."
12+
> `If you define or delete any default operation in the type 'type-name', define or delete them all (c.21).`
1213
13-
**C++ Core Guidelines**:
14+
**C++ Core Guidelines**:\
1415
[C.21: If you define or =delete any default operation, define or =delete them all](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c21-if-you-define-or-delete-any-default-operation-define-or-delete-them-all)
1516

16-
Special operations like constructors are assumed to alter behavior of types so that they rely more on language mechanisms to automatically enforce specific scenarios. The canonical example is resource management. If you explicitly define, default, or delete any of these special operations, it signals you want to avoid any special handling of a type. It's inconsistent to leave the other operations unspecified, that is, implicitly defined as deleted by the compiler.
17+
Special operations such as constructors are assumed to alter the behavior of types so they rely more on language mechanisms to automatically enforce specific scenarios. The canonical example is resource management. If you explicitly define, default, or delete any of these special operations, it signals you want to avoid any special handling of a type. It's inconsistent to leave the other operations unspecified, that is, implicitly defined as deleted by the compiler.
1718

1819
## Remarks
1920

20-
- This check implements "the rule of five" which treats the following operations as special:
21-
- copy constructors;
22-
- move constructors;
23-
- copy assignment operators;
24-
- move assignment operators;
21+
- This check implements the *rule of five*, which treats the following operations as special:
22+
- copy constructors,
23+
- move constructors,
24+
- copy assignment operators,
25+
- move assignment operators, and
2526
- destructors.
2627
- The rule doesn't check if operations are defined in the same way. It's okay to mix deleted and defaulted operations with explicitly defined ones. However, you must specify all of them if you specify any of them.
2728
- Access levels aren't important and can also be mixed.
2829
- The warning flags the first non-static function definition of a type, once per type.
30+
31+
## Example
32+
33+
In this example, `warning::S` defines only a default constructor and a destructor. The `no_warning::S` declaration defines all five special member functions.
34+
35+
```cpp
36+
// C26432.cpp
37+
namespace warning
38+
{
39+
struct S
40+
{
41+
S() noexcept {}
42+
~S() {} // C26432 because only the constructor and destructor are explicitly defined.
43+
};
44+
}
45+
46+
namespace no_warning
47+
{
48+
struct S
49+
{
50+
S() noexcept {}
51+
S(const S& s) = default;
52+
S(S&& s) = default;
53+
S& operator=(const S& s) = default;
54+
S& operator=(S&& s) = default;
55+
~S() {}
56+
};
57+
}
58+
```

docs/code-quality/c26434.md

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,49 @@
11
---
22
title: C26434
3-
ms.date: 11/15/2017
3+
description: "Microsoft C++ Code Analysis warning C26434 for the C++ Core Guidelines case C.128."
4+
ms.date: 08/21/2020
45
ms.topic: "conceptual"
56
f1_keywords: ["C26434"]
67
helpviewer_keywords: ["C26434"]
78
ms.assetid: 7f66477f-da66-444a-a6e3-44513d7d7e31
89
---
910
# C26434 DONT_HIDE_METHODS
1011

11-
"Function hides a non-virtual function."
12+
> `Function 'derived::function' hides a non-virtual function 'base::function' (c.128).`
1213
1314
## C++ Core Guidelines
1415

1516
[C.128: Virtual functions should specify exactly one of virtual, override, or final](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md)
1617

17-
Introducing a function which has the same name as a non-virtual function in a base class is like introducing a variable name which conflicts with a name from outer scope. Furthermore, if signatures of functions mismatch, the intended overriding may turn into overloading. Overall, name hiding is dangerous and error-prone.
18-
1918
## Remarks
2019

21-
- Only non-overriding functions in current class are checked.
20+
When you introduce a function that has the same name as a non-virtual function in a base class, you may get unexpected behavior. It's like introducing a variable name which conflicts with a name from an outer scope. For example, you may have intended to override a base class function. If the signatures of the functions don't match, the override you intended may turn into an overload instead. In general, name hiding is dangerous and error-prone.
21+
22+
In the Core Guidelines checks:
23+
24+
- Only non-overriding functions in the current class are checked.
2225
- Only non-virtual functions of base classes are considered.
2326
- No signature matching is performed. Warnings are emitted if unqualified names match.
2427

25-
## See also
28+
## Example
2629

27-
[C.128: Virtual functions should specify exactly one of virtual, override, or final](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md)
30+
This example demonstrates how a derived class can hide non-virtual functions, and how virtual functions allow both overloads and overrides:
31+
32+
```cpp
33+
// C26434.cpp
34+
struct Base
35+
{
36+
virtual ~Base() = default;
37+
virtual void is_virtual() noexcept {}
38+
void not_virtual() noexcept {}
39+
};
40+
41+
struct Derived : Base
42+
{
43+
void is_virtual() noexcept override {} // Okay, override existing function
44+
virtual void is_virtual(int i) noexcept {} // Add a virtual overload for function
45+
void not_virtual() noexcept {} // C26434, hides a non-virtual function
46+
virtual void not_virtual(int i) noexcept {} // C26434, and parameters ignored
47+
};
48+
49+
```

0 commit comments

Comments
 (0)