Expensive std::function type definition
Definition of std::function type uses pass-by-value semantics
for arguments that are expensive to copy
Since R2024a
Description
This defect occurs if you use pass-by-value semantics for an argument that is expensive
to copy when defining an std::function type. For
example:
std::function<bool(std::string)> myFunc;
std::function type myFunc stores a
callable entity that accepts an std::string object by value. Because
this type copies expensive std::string objects, Polyspace® reports a defect.
Polyspace considers an argument to be expensive if its size is greater than 2
* sizeof(void*).
Risk
When defining an std::function type, if you specify pass-by-value
semantics, then the compiler copies the argument when a target is invoked using the
std::function type. Consider this
code:
#include <string>
#include <functional>
using StringConsumer = std::function<void(std::string)>; // takes by value
void InvokeConsumer(StringConsumer consumer, const std::string& inputText)
{
// std::function<void(std::string)> forces a copy here
consumer(inputText);
}
void main(const std::string& message)
{
InvokeConsumer([](const std::string &text){}, message);
}
StringConsumer uses
pass-by-value semantics. The compiler copies the string variable
inputText when invoking consumer(inputText) and
then passes a reference to this copy to the underlying lambda [](const std::string
&text) {}.Copying an expensive argument and then passing a reference to the copy is unnecessarily inefficient.
Fix
Use pass-by-reference semantics in the std::function type
definition:
#include <string>
#include <functional>
using StringConsumer = std::function<void(const std::string&)>; // takes by const-ref
void InvokeConsumer(StringConsumer consumer, const std::string& inputText)
{
// std::function<void(const std::string&)> does not copy
consumer(inputText);
}
void main(const std::string& message)
{
InvokeConsumer([](const std::string &text){}, message);
}
Performance improvements 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_STD_FUNCTION
|
| Impact: Low |
PQL Name:
std.defects.EXPENSIVE_STD_FUNCTION
|
Version History
Introduced in R2024a
See Also
Find defects
(-checkers) | Expensive pass by
value | Expensive return by
value | Expensive copy in a range-based
for loop iteration | Expensive local variable
copy
Topics
- Interpret Polyspace Bug Finder Results in Polyspace Platform User Interface
- Interpret Bug Finder Results in Polyspace Access Web Interface (Polyspace Access)
- Address Polyspace Results Through Bug Fixes or Justifications
- Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access)
- Expensive-to-Read Objects in Bug Finder