How can std::string_view be constexpr?

726 views Asked by At

I tried to find the answer on SO but failed. Sorry if this is a duplicate. I will close the question then.

Could you explain the difference between:

constexpr const char Str1[] = "qwerty";
constexpr auto Str1Size = sizeof(Str1) - 1;

and

constexpr std::string_view Str2{"qwerty"};
constexpr auto Str2Size = Str2.size();

I saw the second variant today and failed to understand. AFAIU std::string_view is a dynamic object, so memory will be dynamically allocated. So how can be this constexpr?

Also, if these variants are really both okay, i.e. are compile-time, then what is their difference? AFAIK, Str2 will not have '\0' and the end of it. Is it all?

1

There are 1 answers

1
Jan Schultke On BEST ANSWER

AFAIU std::string_view is a dynamic object, so memory will be dynamically allocated. So how can be this constexpr?

std::string_view is not dynamically allocated. It is essentially a const char* to the character data and the string length, combined into one object. This can obviously be constexpr. You might be thinking of std::string, which is dynamically allocated.

Note that

constexpr const char* str = "qwerty";

... is valid, since "qwerty" is not dynamically allocated but has static storage duration. str points to this string literal. If you wrap this in a std::string_view, the str pointer gets copied. None of this involves dynamic allocation.

Also, if these variants are really both okay, i.e. are compile-time, then what is their difference? AFAIK, Str2 will not have '\0' and the end of it. Is it all?

The null terminator is the only significant difference. std::string_view is not guaranteed to be null-terminated, so you lose safe access(1) to it when wrapping the character data in a std::string_view. std::string_view is also a standard library container, and has an interface which is much nicer to work with. You can create substrings with .substr, etc.


(1) Specifically, the null terminator is still contained in the string data, which can be accessed with .data(). However, an arbitrary std::string_view may not be null-terminated, making it unsafe and bug-prone to rely on it being null-terminated. There is also no safe way to check whether a std::string_view is null-terminated at run-time, so either you (blindly) believe it, or you assume that it isn't.