std::string
constructionA constant string object is constructed form constant data resulting in inefficient code
This defect is raised when both of these conditions are true:
You construct a std::string object from constant data such as a
string literal or the output of a constexpr function.
The std::string object remains constant or unmodified after the
construction.
This checker does not flag class member variables, and string literals that are function arguments.
Consider an std::string objects in a code block that contains
constant data which remains unmodified after construction. Every time the code block
executes, a new std::string object is constructed with no change in its
content. Repeated construction of such an std::string object with no
modification of the content is inefficient and difficult to detect. Consider this
code:
#include <string>
constexpr char* getStrPtr() {
return "abcd";
}
void foo(){
std::string s1 = "abcd";
std::string s2{"abcd"};
std::string s3 = getStrPtr();
}
int main(){
//...
for(int i = 0; i<10000; ++i)
foo();
}foo is called 10000 times.
Each time foo is called, s1, s2,
and s3 are constructed from the same constant string literal
abcd, resulting in inefficient code. Because such inefficient and
confusing code compiles and functions correctly, the inefficient construction of
std::string objects from constant data might not be noticed.The fix for this defect depends on the intended use of the constant data.
You can store the constant data in a static string object if
you need the functionalities of std::string class.
You can use the constant data directly as temporary literals if you do not need to reuse the data.
You can store the constant data by using a const character
array or an std::string_view object if you do not need the
functionalities of the std::string class.
std::string_view is supported by C++17 and later.
Consider this code:
constexpr char* getStrPtr() {
return "abcd";
}
void foo(){
static std::string s3 = getStrPtr();
std::string_view s3a{s3};
}
int main(){
//...
for(int i = 0; i<10000; ++i)
foo();
}std::string object s3 is declared as
static. Because s3 is static, it
is constructed only once even if foo is called 10000
times. The std::string_view object s2 shows the
content of s3 and avoids constructing an std::string
object every time foo is called. By using
std::string_view and static objects, you avoid
unnecessary construction of constant std::string objects. This method
also clarifies that the objects s3 and s3a represent
the same data.Performance improvements might vary based on the compiler, library implementation, and environment that you are using.
| Group: Performance |
| Language: C++ |
| Default: Off |
Command-Line Syntax:
EXPENSIVE_CONSTANT_STD_STRING |
| Impact: Medium |