Our team is working with a 10+ years old C++ code base and recently switched to a C++17 compiler. So we are looking for ways to modernize our code. In a conference talk on YouTube I heard the suggestion, to replace const char*
global strings with constexpr string_view
.
Since we got quite a number of such const char*
global string constants in our code, I want to ask if there are any gotchas or potential issues we need to be aware of?
These issues might be worth being aware of:
std::string_view
doesn't need to be null
-terminated. So if you replace some const char*
by string_view
and replace the construction of a previously null
-terminated char*
substring by a string_view
via std::string_view::substr
, you can't pass the underlying pointer to an API that expects a null
-terminated string. Example (without UB, but that is easily constructable, too):
void legacy(const char *str) {
std::printf("%s\n", str);
}
constexpr std::string_view sv1 = "abcde";
constexpr std::string_view sv2 = sv1.substr(0, 2); // view on "ab"
legacy(sv2.data()); // Not intended: prints "abcde"
While you can implicitly construct a std::string
from a const char*
, you cannot do that with a std::string_view
. The idea is that a deep copy shouldn't happen under the cover, but only when explicitly requested. Example:
std::map<std::string, int> m;
constexpr std::string_view sv = "somekey";
constexpr const char *old = "somekey";
m[old] = 42; // works as expected
m[sv] = 42; // fails to compile
m[std::string(sv)] = 42; // be explicit, this is ok
Depending on the existing usage of the global const char*
instances in your project, this behavior might require manual intervention at various places.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With