Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is string_view{ nullptr, 0 } valid?

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 nullptr constructors, 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::string using basic_string(nullptr, 0); and std::string_view using basic_string_view(nullptr, 0); and thus they were not included into the main text of the proposal.

Bonus questions:

  • When the text says "citation source is the same", what is the reference?
  • The final paragraph speaks of "the legal, yet not legitimate case". I understand the meaning of "legal", but what exactly is "not legitimate" about this use?

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) };
}
like image 486
IInspectable Avatar asked Dec 03 '25 17:12

IInspectable


1 Answers

Is [nullptr, nullptr) considered a "valid range" in C++?

Yes. [iterator.requirements.general]/10:

A sentinel s is called reachable from an iterator i if and only if there is a finite sequence of applications of the expression ++i that makes i == s. If s is reachable from i, [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.

like image 84
T.C. Avatar answered Dec 06 '25 07:12

T.C.