Expensive copy in a range-based for loop iteration
The loop variable of a range-based for
loop is copied from the
range elements instead of being referenced resulting in inefficient code
Since R2020b
Description
This defect occurs when the loop variable of a range-based for
loop is
copied from the range elements instead of reading the range elements by reference. Copy the
range elements only when its necessary because copying them might result in inefficient code.
This defect is raised when the loop variable is unmodified and any of these conditions are true:
The copied loop variable is a large trivially copyable type variable. Copying a trivially copyable object is more expensive than referencing it when the object is large.
The copied loop variable is a nontrivially copyable type. Copying such an object might require an external function call, which is more expensive than referencing it. To check whether an object is nontrivially copyable, use the function
std::is_trivially_copyable
. For more details about this function, seestd::is_trivially_copyable
in the C++ reference.
Risk
Range-based for
loops can become inefficient when an expensive copy
of the loop variable is made in each iteration of the loop. Consider this
code:
void foo( std::map<std::string, std::string> const& property_map ) { for( std::pair< const std::string, std::string > const property: property_map) {} }
The loop variable property
is declared as a const
instead of const&
. In each iteration of the for
loop, an std::pair
object is copied from the map
property_maps
to the loop variable property
. Because
of the missing &
in the declaration of propert
, an
expensive copy operation is done in each iteration instead of a referencing operation,
resulting in inefficient code. Because this code compiles and functions correctly, the
inefficient for
loops might not be noticed. For similar source of
inefficiencies, see Expensive pass by
value
and Expensive return by
value
.
Fix
To fix this defect, declare the loop variable of a range-based for
loop as a const&
. Consider this
code:
void foo( std::map<std::string, std::string> const& property_map ) { for( std::pair< const std::string, std::string > const& property: property_map) {} }
property
is declared as a
const&
, the variable references a different element of the map
property_map
in each loop iteration, without copying any resource. By
preventing an expensive copy in each iteration, the code becomes more efficient.Performance improvements might vary based on the compiler, library implementation, and environment that you are using.
Examples
Result Information
Group: Performance |
Language: C++ |
Default: Off |
Command-Line Syntax:
EXPENSIVE_RANGE_BASED_FOR_LOOP_ITERATION |
Impact: Medium |
Version History
Introduced in R2020b
See Also
Find defects
(-checkers)
| Expensive pass by value
| Expensive return by
value
| Expensive local variable
copy
Topics
- Interpret Bug Finder Results in Polyspace Desktop User Interface
- Interpret Bug Finder Results in Polyspace Access Web Interface (Polyspace Access)
- Address Results in Polyspace User Interface Through Bug Fixes or Justifications
- Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access)