std::string_view 文字是否保证以 null 结尾?
Is a std::string_view literal guaranteed to be null-terminated?
我知道一个琐碎的 std::string_view
不能保证以 null 结尾。但是,我不知道 std::string_view
文字是否保证以 null 结尾。
例如:
#include <string_view>
using namespace std::literals;
int main()
{
auto my_sv = "hello"sv;
}
C++17 或更高版本是否保证 my_sv.data()
以 null 终止?
=== 下面更新了===
以下全部来自n4820:
- As per 5.13.5.14, a string literal is null-terminated.
- As per 5.13.8, a user-defined-string-literal is composed of a string literal plus a custom suffix. Say,
"hello"sv
, hello
is the string literal, sv
is the suffix.
- As per 5.13.8.5,
"hello"sv
is treated as a call of the form operator "" sv(str, len);
as per 5.13.5.14, str
is
null-terminated.
- As per 21.4.2.1,
sv
's data()
must return str
.
他们能证明 "hello"sv.data()
保证由 C++ 标准以 null 终止吗?
所以让我们把简单的部分放在一边。没有 string_view
曾经是“NUL 终止的”,因为对象代表一定大小的字符范围。即使您从 NUL 终止的字符序列创建 string_view
,string_view
本身 仍然不是“NUL 终止的”。
你真正要问的问题是:实现是否有一些回旋余地使语句 "some literal"sv
产生 string_view
其 data
成员 确实not 指向由 "some literal"
表示的以 NUL 结尾的字符串文字?也就是说,是这样的:
string_view s = "some literal"sv;
允许以任何方式与此不同的行为:
const char *lit = "some literal";
string_view s(lit, <number of chars in of lit>);
在后一种情况下,s.data()
保证是指向字符串文字的指针,因此您可以将该指针视为指向以 NUL 结尾的字符串的指针。你问的是前者是否同样有效。
让我们调查一下。 definition for the operator""sv
overloads are stated to be:
constexpr string_view operator""sv(const char* str, size_t len) noexcept;
Returns: string_view{str, len}
.
这是此函数行为的标准规范:它 return 是一个 string_view
,指向 str
提供的内存。因此,实现不能分配一些隐藏的内存并使用它或其他任何东西; returned string_view::data
需要 到 return 与 str
.
相同的指针
现在,这给我们带来了另一个问题:str
是否需要 成为以 NUL 结尾的字符串?也就是说,编译器看到您正在使用 sv
UDL 实现并因此从它要为作为 str
传递的字符串文字创建的数组中删除 NUL 字符是否合法?
我们来看看how UDLs for strings work:
If L
is a user-defined-string-literal, let str
be the literal without its ud-suffix and let len
be the number of code units in str
(i.e., its length excluding the terminating null character). The literal L
is treated as a call of the form
operator "" X(str, len)
注意我强调的词组。我们知道“没有 ud 后缀的文字”的行为。第二个短语特别提到了 str
的预期 NUL 终止符。我想说 str
将被赋予一个文字字符串,这是一个非常明确的声明。并且该文字字符串将按照 C++ 中的常规字符串文字规则构建,因此将以 NUL 结尾。
鉴于以上情况,我认为可以肯定地说这里没有实施的回旋余地。由 UDL 编辑的 string_view
return 必须 指向由 UDL 中指定的字符串文字定义的数组,并且像任何其他字符串文字一样,该数组 将以NUL结尾。
话虽如此,请审阅我的第一段。您不应编写任何假定 string_view
以 NUL 结尾的代码。即使 string_view
的创建者和消费者紧挨着,我也会称之为代码味道。
我知道一个琐碎的 std::string_view
不能保证以 null 结尾。但是,我不知道 std::string_view
文字是否保证以 null 结尾。
例如:
#include <string_view>
using namespace std::literals;
int main()
{
auto my_sv = "hello"sv;
}
C++17 或更高版本是否保证 my_sv.data()
以 null 终止?
=== 下面更新了===
以下全部来自n4820:
- As per 5.13.5.14, a string literal is null-terminated.
- As per 5.13.8, a user-defined-string-literal is composed of a string literal plus a custom suffix. Say,
"hello"sv
,hello
is the string literal,sv
is the suffix.- As per 5.13.8.5,
"hello"sv
is treated as a call of the formoperator "" sv(str, len);
as per 5.13.5.14,str
is null-terminated.- As per 21.4.2.1,
sv
'sdata()
must returnstr
.
他们能证明 "hello"sv.data()
保证由 C++ 标准以 null 终止吗?
所以让我们把简单的部分放在一边。没有 string_view
曾经是“NUL 终止的”,因为对象代表一定大小的字符范围。即使您从 NUL 终止的字符序列创建 string_view
,string_view
本身 仍然不是“NUL 终止的”。
你真正要问的问题是:实现是否有一些回旋余地使语句 "some literal"sv
产生 string_view
其 data
成员 确实not 指向由 "some literal"
表示的以 NUL 结尾的字符串文字?也就是说,是这样的:
string_view s = "some literal"sv;
允许以任何方式与此不同的行为:
const char *lit = "some literal";
string_view s(lit, <number of chars in of lit>);
在后一种情况下,s.data()
保证是指向字符串文字的指针,因此您可以将该指针视为指向以 NUL 结尾的字符串的指针。你问的是前者是否同样有效。
让我们调查一下。 definition for the operator""sv
overloads are stated to be:
constexpr string_view operator""sv(const char* str, size_t len) noexcept;
Returns:
string_view{str, len}
.
这是此函数行为的标准规范:它 return 是一个 string_view
,指向 str
提供的内存。因此,实现不能分配一些隐藏的内存并使用它或其他任何东西; returned string_view::data
需要 到 return 与 str
.
现在,这给我们带来了另一个问题:str
是否需要 成为以 NUL 结尾的字符串?也就是说,编译器看到您正在使用 sv
UDL 实现并因此从它要为作为 str
传递的字符串文字创建的数组中删除 NUL 字符是否合法?
我们来看看how UDLs for strings work:
If
L
is a user-defined-string-literal, letstr
be the literal without its ud-suffix and letlen
be the number of code units instr
(i.e., its length excluding the terminating null character). The literalL
is treated as a call of the formoperator "" X(str, len)
注意我强调的词组。我们知道“没有 ud 后缀的文字”的行为。第二个短语特别提到了 str
的预期 NUL 终止符。我想说 str
将被赋予一个文字字符串,这是一个非常明确的声明。并且该文字字符串将按照 C++ 中的常规字符串文字规则构建,因此将以 NUL 结尾。
鉴于以上情况,我认为可以肯定地说这里没有实施的回旋余地。由 UDL 编辑的 string_view
return 必须 指向由 UDL 中指定的字符串文字定义的数组,并且像任何其他字符串文字一样,该数组 将以NUL结尾。
话虽如此,请审阅我的第一段。您不应编写任何假定 string_view
以 NUL 结尾的代码。即使 string_view
的创建者和消费者紧挨着,我也会称之为代码味道。