Is this a valid C++ program?
#include <string_view>
int main() {
auto _ = std::string_view{ nullptr, 0 };
}
Specifically, is the expression string_view{ nullptr, 0 } well-defined? The specification for this constructor under [string.view.cons] reads:
Preconditions:
[str, str + len)is a valid range.
With that, another way of phrasing this question would be: Is [nullptr, nullptr) considered a "valid range" in C++?
I am confused mostly due to the wording used in P2166. It proposes rejecting the construction of a string_view from a nullptr alone. This is well justified. I am, however, failing to comprehend the section titled "Further Discourse" that explains why the "sized constructor counterparts" were excluded:
As a development of the above proposal it seems logical to remove sized counterpart of
nullptrconstructors, as the behavior is undefined if[s, s + count)is not a valid range (citation source is the same). That is, the following statements are suggested where appropriate:basic_string(nullptr_t, size_t) == delete; constexpr basic_string_view(nullptr_t, size_t) == delete;These changes will break the legal, yet not legitimate case of constructing
std::stringusingbasic_string(nullptr, 0);andstd::string_viewusingbasic_string_view(nullptr, 0);and thus they were not included into the main text of the proposal.
Bonus questions:
Clarification: I'm not constructing a string_view from the nullptr/0 literals, i.e., I'm not trying to evade or obfuscate a default constructor call. The actual use case is closer to this:
#include <string_view>
struct X {
operator char const*() const { return nullptr; }
private:
friend size_t len(X const&) { return 0; }
};
int main() {
X const x{};
auto _ = std::string_view{ x, len(x) };
}
Is
[nullptr, nullptr)considered a "valid range" in C++?
Yes. [iterator.requirements.general]/10:
A sentinel
sis called reachable from an iteratoriif and only if there is a finite sequence of applications of the expression++ithat makesi == s. Ifsis reachable fromi,[i, s)denotes a valid range.
There is a finite sequence of applications of ++i (viz., a sequence of zero such applications) to make (char*) nullptr compare equal to (char*) nullptr + 0. It therefore is a valid (and empty) range.
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