Skip to content

Commit 9584d4c

Browse files
author
Colin Robertson
authored
Merge pull request MicrosoftDocs#1932 from dmitrykobets/patch-1
Document new rule C26817
2 parents 3c886b0 + fd82653 commit 9584d4c

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

docs/code-quality/c26817.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
---
2+
title: C26817
3+
description: "Reference for Microsoft C++ Code Analysis warning C26817 in Visual Studio."
4+
ms.date: 02/24/2020
5+
ms.topic: "reference"
6+
f1_keywords: ["C26817"]
7+
helpviewer_keywords: ["C26817"]
8+
---
9+
# C26817
10+
11+
> Potentially expensive copy of variable *name* in range-for loop. Consider making it a const reference (es.71).
12+
13+
For more information, see [ES.71 notes](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#note-217) in the C++ Core Guidelines.
14+
15+
## Example
16+
17+
If a range-for loop variable isn't explicitly marked as a reference, it gets a copy of each element iterated over:
18+
19+
```cpp
20+
#include <vector>
21+
22+
class MyComplexType {
23+
int native_array[1000];
24+
// ...
25+
};
26+
27+
void expensive_function(std::vector<MyComplexType>& complex_vector_ref)
28+
{
29+
for (auto item: complex_vector_ref)
30+
{
31+
// At each iteration, item gets a copy of the next element
32+
// ...
33+
}
34+
for (MyComplexType item: complex_vector_ref)
35+
{
36+
// It happens whether you use the auto keyword or the type name
37+
// ...
38+
}
39+
}
40+
```
41+
42+
This behavior is fine for scalars (pointers, arithmetic types, and so on), but for larger types, the copying may become expensive.
43+
44+
## Solution
45+
46+
To fix this issue, if the loop variable isn't mutated anywhere in the loop, make it a const reference:
47+
48+
```cpp
49+
#include <vector>
50+
51+
class MyComplexType {
52+
int native_array[1000];
53+
// ...
54+
};
55+
56+
void less_expensive_function(std::vector<MyComplexType>& complex_vector_ref)
57+
{
58+
for (const auto& item: complex_vector_ref)
59+
{
60+
// item no longer gets a copy of each iterated element
61+
// ...
62+
}
63+
for (const MyComplexType& item: complex_vector_ref)
64+
{
65+
// item no longer gets a copy of each iterated element
66+
// ...
67+
}
68+
}
69+
```
70+
71+
The **const** keyword makes the loop variable immutable. Use of a non-const reference may cause potentially unwanted side effects in the original container elements. If you need to modify only the local loop variable, the potentially expensive copying is unavoidable.

0 commit comments

Comments
 (0)