Date: Mon, 2 Feb 2026 14:06:44 -0500
On Mon, Feb 2, 2026 at 1:35 PM Arthur O'Dwyer via Std-Proposals
<std-proposals_at_[hidden]> wrote:
>
> On Mon, Feb 2, 2026 at 11:38 AM Thiago Macieira via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>
>> On Monday, 2 February 2026 00:00:04 Pacific Standard Time FPE via Std-Proposals
>> wrote:
>> > 4. On Thiago Macieira's security concerns (embedded nulls): Great points –
>> > these are real risks in untrusted input scenarios. However, going back to
>> > string_view's original goals: it accelerates code by trusting input
>> > (avoiding repeated strlen) and consolidating (ptr, len) into one object.
>>
>> I don't have a problem if one declares that modifying the string underneath
>> the container and inserting a NUL or removing the one that terminates is
>> unsupported. That's usually not a problem. Strings are easy to retain
>> unmodified.
>>
>> What I have a problem with is trusting basic_string / basic_string_view's
>> size() and requiring them to not have an embedded NUL. If cstring_view stores
>> a size value, it must be obtained from strlen() on construction.
>
>
> I agree that it's weird, but, wouldn't you agree that the currently proposed behavior of cstring_view is consistent with the standard-since-C++17 behavior of string_view?
> auto s = std::string("hello\0world", 11);
> auto sv = std::string_view(s); // gets 11 characters, not 5
> auto cv = std::cstring_view(s); // should get 11 characters, not 5, right? for consistency?
> auto sv2 = std::string_view(std::cstring_view(s)); // should get 11 characters, not 5, right? for consistency?
> That is, constructing from a std::string and constructing from a const char* have always (since C++17) behaved weirdly differently. We can't get rid of that weirdness, but we can at least be consistent with it. Being weird and inconsistent would be worse, wouldn't it?
Is consistency between `cstring_view` and `string_view` the important
thing to be consistent with? Think about the use cases here.
The whole point of `cstring_view` is that it can be used in more
places than `string_view`. And those "more places" are APIs that
require NUL terminated strings. That's the whole point of the class.
So there are things you could do with `cv` that you could never do
with `sv`. And if you use `cv` in those places, the results of those
operations ought to be consistent with using `cv` directly. That is,
if you pass `cv.data()` to an API that returns its NUL-terminated
length, that result should be equivalent to `cv.size()`.
*That* is the consistency that matters.
If `cstring_view` is going to be a "C string", then it should be
consistent with the behavior of a "C string". People don't create
`cstring_view`s to match `string_view` APIs. They create
`cstring_view`s to interact with C APIs. So the result of
`cstring_view`'s native interactions should be consistent with C APIs.
I don't know why anybody would want to do
`std::string_view(std::cstring_view(s))`. And if they did, I don't
know why they would expect them to result in the same string in all
cases when C strings are known to be a less-capable form of string
than C++ strings.
<std-proposals_at_[hidden]> wrote:
>
> On Mon, Feb 2, 2026 at 11:38 AM Thiago Macieira via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>
>> On Monday, 2 February 2026 00:00:04 Pacific Standard Time FPE via Std-Proposals
>> wrote:
>> > 4. On Thiago Macieira's security concerns (embedded nulls): Great points –
>> > these are real risks in untrusted input scenarios. However, going back to
>> > string_view's original goals: it accelerates code by trusting input
>> > (avoiding repeated strlen) and consolidating (ptr, len) into one object.
>>
>> I don't have a problem if one declares that modifying the string underneath
>> the container and inserting a NUL or removing the one that terminates is
>> unsupported. That's usually not a problem. Strings are easy to retain
>> unmodified.
>>
>> What I have a problem with is trusting basic_string / basic_string_view's
>> size() and requiring them to not have an embedded NUL. If cstring_view stores
>> a size value, it must be obtained from strlen() on construction.
>
>
> I agree that it's weird, but, wouldn't you agree that the currently proposed behavior of cstring_view is consistent with the standard-since-C++17 behavior of string_view?
> auto s = std::string("hello\0world", 11);
> auto sv = std::string_view(s); // gets 11 characters, not 5
> auto cv = std::cstring_view(s); // should get 11 characters, not 5, right? for consistency?
> auto sv2 = std::string_view(std::cstring_view(s)); // should get 11 characters, not 5, right? for consistency?
> That is, constructing from a std::string and constructing from a const char* have always (since C++17) behaved weirdly differently. We can't get rid of that weirdness, but we can at least be consistent with it. Being weird and inconsistent would be worse, wouldn't it?
Is consistency between `cstring_view` and `string_view` the important
thing to be consistent with? Think about the use cases here.
The whole point of `cstring_view` is that it can be used in more
places than `string_view`. And those "more places" are APIs that
require NUL terminated strings. That's the whole point of the class.
So there are things you could do with `cv` that you could never do
with `sv`. And if you use `cv` in those places, the results of those
operations ought to be consistent with using `cv` directly. That is,
if you pass `cv.data()` to an API that returns its NUL-terminated
length, that result should be equivalent to `cv.size()`.
*That* is the consistency that matters.
If `cstring_view` is going to be a "C string", then it should be
consistent with the behavior of a "C string". People don't create
`cstring_view`s to match `string_view` APIs. They create
`cstring_view`s to interact with C APIs. So the result of
`cstring_view`'s native interactions should be consistent with C APIs.
I don't know why anybody would want to do
`std::string_view(std::cstring_view(s))`. And if they did, I don't
know why they would expect them to result in the same string in all
cases when C strings are known to be a less-capable form of string
than C++ strings.
Received on 2026-02-02 19:06:56
