rspec/rules/S7121/cfamily/rule.adoc

58 lines
1.8 KiB
Plaintext

Unnecessary calls to `c_str()` or `data()` reduce readability and performance.
== Why is this an issue?
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.
[source,cpp,diff-id=1,diff-type=noncompliant]
----
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.
[source,cpp,diff-id=1,diff-type=compliant]
----
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()`.
[source,cpp]
----
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`.
== Resources
=== Related rules
* S6231 - "std::string_view" and "std::span" parameters should be directly constructed from sequences