web-dev-qa-db-ja.com

std :: string_viewリテラルはnullで終了することが保証されていますか?

些細な_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で終了することが保証されていますか?

===以下を更新します===

以下はすべて n482 からのものです。

  1. 5.13.5.14に従い、文字列リテラルはnullで終了します。
  2. 5.13.8に従って、user-defined-string-literalは文字列リテラルとカスタムサフィックスで構成されます。たとえば、_"hello"sv_、helloは文字列リテラル、svはサフィックスです。
  3. 5.13.8.5に従い、_"hello"sv_は5.13.5.14のようにoperator "" sv(str, len);の形式の呼び出しとして扱われ、strはnullで終了します。
  4. 21.4.2.1に従い、svdata()strを返す必要があります。

"hello"sv.data()がC++標準によってnullで終了することが保証されていることを証明できますか?

12
xmllmx

では、簡単な部分を邪魔にならないようにしましょう。オブジェクトが特定のサイズの文字範囲を表すという意味で、_string_view_が「NULで終了する」ことはありません。 NULで終了する文字のシーケンスから_string_view_を作成しても、_string_view_itselfはまだ「NULで終了」されていません。

あなたが本当に尋ねている質問はこれです:実装はステートメント_"some literal"sv_に_string_view_を生成する余裕がありますか?dataメンバーdoes not_"some literal"_で表されるNULで終了する文字列リテラルを指すつまり、これは:

_string_view s = "some literal"sv;
_

any wayとは異なる動作が許可されています:

_const char *lit = "some literal";
string_view s(lit, <number of chars in of lit>);
_

後者の場合、s.data()は文字列リテラルへのポインターであることが保証されているため、そのポインターをNUL終了文字列へのポインターとして扱うことができます。前者も同様に有効であるかどうかを尋ねています。

調べてみましょう。 _operator""sv_オーバーロードの定義は次のように記述されています

_constexpr string_view operator""sv(const char* str, size_t len) noexcept;
_

戻り値:_string_­view{str, len}_。

これは、この関数の動作の標準仕様です。strによって提供されるメモリを指す_string_view_を返します。したがって、実装はいくつかの隠しメモリを割り当てて、それを使用することはできません。返された_string_view::data_/ strと同じポインタを返すには、が必要です。

さて、これは別の質問に導きます:strrequiredはNULで終了する文字列ですか?つまり、コンパイラがsv UDL実装を使用していることを認識しているため、strとして渡された文字列リテラル用に作成しようとしていた配列からNUL文字を削除できます。 ?

文字列のUDLの仕組み を見てみましょう。

Lがユーザー定義の文字列リテラルの場合、strd-suffixなしのリテラルとし、lenを数値にしますstr内のコード単位の数(つまり、長さ終端のヌル文字を除く)。リテラルLは、次の形式の呼び出しとして扱われます

_operator "" X(str, len)
_

私が強調したフレーズに注意してください。 「ud接尾辞のないリテラル」の動作はわかっています。そして、2番目の句は、strに期待されるNULターミネーターについて具体的に述べています。これは、strにリテラル文字列が与えられるというかなり明確なステートメントだと思います。そして、そのリテラル文字列は、C++の通常の文字列リテラルルールに従って作成されるため、NULで終了します。

以上を踏まえると、ここで実装する余地はないと言っても差し支えないと思います。 UDLによって返される_string_view_mustは、UDLで指定された文字列リテラルによって定義された配列を指し、他の文字列リテラルと同様に、その配列willはNULで終了します。

please最初の段落を確認してください。 _string_view_がNULで終了することを前提とするコードは記述しないでください。 _string_view_の作成者であり、コンシューマーである場合でも、コードの匂いと呼んでもかまいません。

9
Nicol Bolas