In the process of refactoring code from C to C++, it can easily happen that redundant calls to c_str()
or data()
on
standard strings get introduced when the original object could be used directly.
void takeString(std::string const& dest);
void takeStringView(std::string_view dest);
void func(std::string const& src) {
takeString(src.c_str()); // Noncompliant: redundant copy
takeStringView(src.c_str()); // Noncompliant: redundant crossing of the content
takeStringView(src.data()); // Noncompliant: redundant crossing of the content
}
Not only is this unnecessary step a readability issue, but it will force the creation of useless intermediary strings, or require searching the
content of a string for the null-terminator, reducing the performance. The call to c_str()
or data()
should be removed.
void takeString(std::string const& dest);
void takeStringView(std::string_view dest);
void func(std::string const& src) {
takeString(src); // Compliant
takeStringView(src); // Compliant
takeStringView(src); // Compliant
}
Exception
This rule does not raise when explicitly creating a string or a string_view from c_str()
.
void takeString(std::string const& dest);
void func(std::string const& src) {
takeString(std::string(src.c_str())); // Compliant by exception
}
This operation could be done on purpose in the rare case where src
is a string containing embedded null-terminators, in order to only
keep the content up to the first null-terminator in dest
.