Date: Fri, 6 Feb 2026 07:54:34 +0100
>
> I don’t think that we need a wrapper for char*. The only thing you would
> gain is member functions instead of free standing functions. This only
> comes down to taste and does not warrant an additional type.
>
> The primary reason I see for a cstring_view is to improve safety (as long
> as we are in C++ and not C). This only works if cstring_view does not only
> store a pointer, but also a size (or rather a capacity). Someone has
> allocated some memory for this string and this gives us some capacity
> (which might be less than what was allocated depending on how the view is
> constructed). If we access a character inside this view the
> compiler/runtime can do bounds checks (through contracts). This would
> already be much safer even if strlen is less than the capacity saved inside
> the view.
>
Agreed, this feature is pointless if it just wraps a pointer.
> Since we assume a C-style null terminated string, iteration should
> definitely still be until the null character is hit (or maybe until
> strlen). Checking for capacity could be done in addition to this. (Or
> runtime checks through contracts could trigger with out-of-bounds access.)
>
That sounds questionable to me. std::string iteration also doesn't stop at
nulls, and constantly dealing with nested nulls inhibits optimizations like
copying strings with std::memcpy. When looking at the string from a "range
perspective", its size should match the advertised size(). The
null-terminated size is only relevant to C APIs.
> I am not sure if there are any restrictions in the current proposal if the
> cstring_view has to be const. If not, I might be giving a non-const view
> (converted to char*) to a C function which might write to it and change its
> strlen (only making it shorter would be allowed). A size member would then
> be wrong anyway (unless it is supposed to be a capacity). In this sense
> cstring_view would be a little bit like a buffer. This would also mean that
> there does not have to be a terminating null character at the end of the
> capacity. If it is const, there has to be at least one null character
> within the capacity. If the cstring_view is meant as a target for a C
> function to write into it doesn’t even have to include any null character
> when the constructor is called (as the cstring might be uninitialized).
> (Probably, in these cases we could also use a string_view instead; but it
> would improve teachability if we can say: always use cstring_view when
> interfacing with C.)
>
I think it should be const, just like std::string_view. The type is not
suitable for wrapping C APIs anyway, only for calling C APIs with strings
obtained on the C++ side because wrapping C APIs in std::cstring_view (as
currently proposed) results in unnecessary, repeated, and wasteful
computations of the string length which the C API never produces or
consumes.
> I’m not sure if we need cstring_view to be compatible with constexpr. The
> only reason to use cstring_view should be to interface with C. Am I
> mistaken that there are no constexpr C functions? Or are some of the C
> standard library functions marked constexpr when included from C++? Still,
> we don’t need to use a C string if we don’t call any functions from other C
> libraries (which are very likely not constexpr).
>
It doesn't matter whether the C API is constexpr (currently it cannot be,
but perhaps it could be in the future). It still makes sense to make
std::cstring_view constexpr on the C++ side because you can produce
null-terminated strings at compile time (e.g. a string literal or
std::meta::identifier_of) and keep those in constexpr variables. That's
sufficient motivation, even if the contents of those constexpr variables
are only used at runtime.
> I don’t think that we need a wrapper for char*. The only thing you would
> gain is member functions instead of free standing functions. This only
> comes down to taste and does not warrant an additional type.
>
> The primary reason I see for a cstring_view is to improve safety (as long
> as we are in C++ and not C). This only works if cstring_view does not only
> store a pointer, but also a size (or rather a capacity). Someone has
> allocated some memory for this string and this gives us some capacity
> (which might be less than what was allocated depending on how the view is
> constructed). If we access a character inside this view the
> compiler/runtime can do bounds checks (through contracts). This would
> already be much safer even if strlen is less than the capacity saved inside
> the view.
>
Agreed, this feature is pointless if it just wraps a pointer.
> Since we assume a C-style null terminated string, iteration should
> definitely still be until the null character is hit (or maybe until
> strlen). Checking for capacity could be done in addition to this. (Or
> runtime checks through contracts could trigger with out-of-bounds access.)
>
That sounds questionable to me. std::string iteration also doesn't stop at
nulls, and constantly dealing with nested nulls inhibits optimizations like
copying strings with std::memcpy. When looking at the string from a "range
perspective", its size should match the advertised size(). The
null-terminated size is only relevant to C APIs.
> I am not sure if there are any restrictions in the current proposal if the
> cstring_view has to be const. If not, I might be giving a non-const view
> (converted to char*) to a C function which might write to it and change its
> strlen (only making it shorter would be allowed). A size member would then
> be wrong anyway (unless it is supposed to be a capacity). In this sense
> cstring_view would be a little bit like a buffer. This would also mean that
> there does not have to be a terminating null character at the end of the
> capacity. If it is const, there has to be at least one null character
> within the capacity. If the cstring_view is meant as a target for a C
> function to write into it doesn’t even have to include any null character
> when the constructor is called (as the cstring might be uninitialized).
> (Probably, in these cases we could also use a string_view instead; but it
> would improve teachability if we can say: always use cstring_view when
> interfacing with C.)
>
I think it should be const, just like std::string_view. The type is not
suitable for wrapping C APIs anyway, only for calling C APIs with strings
obtained on the C++ side because wrapping C APIs in std::cstring_view (as
currently proposed) results in unnecessary, repeated, and wasteful
computations of the string length which the C API never produces or
consumes.
> I’m not sure if we need cstring_view to be compatible with constexpr. The
> only reason to use cstring_view should be to interface with C. Am I
> mistaken that there are no constexpr C functions? Or are some of the C
> standard library functions marked constexpr when included from C++? Still,
> we don’t need to use a C string if we don’t call any functions from other C
> libraries (which are very likely not constexpr).
>
It doesn't matter whether the C API is constexpr (currently it cannot be,
but perhaps it could be in the future). It still makes sense to make
std::cstring_view constexpr on the C++ side because you can produce
null-terminated strings at compile time (e.g. a string literal or
std::meta::identifier_of) and keep those in constexpr variables. That's
sufficient motivation, even if the contents of those constexpr variables
are only used at runtime.
Received on 2026-02-06 06:54:52
