9

クイック セットアップ: プログラム内で文字列をポインターとサイズとして渡したい。String クラスと、リテラル文字列を構築するためのユーザー定義リテラルがあります。

struct String { const char *ptr; size_t sz; };

inline constexpr String operator "" _string(const char *s, size_t sz) {
  return {s, sz};
}

int main() {
  auto s = "hello"_string;
  s.ptr[0]; //<-- is this access guaranteed to work?
}

標準では、ユーザー定義のリテラル演算子に渡される引数が静的な期間を持つことを指定していますか? つまり、上記のコードは実際には次のように書くのと同じです:

int main() {
  String s{"hello", 5};
}

または、ユーザー定義のリテラルを使用するときに、コンパイラ/リンカーがダングリング ポインターを残すことを許可していますか?

(N4527 のセクション 2.13.8 は、ユーザー定義の文字列リテラル演算子に対する引数のストレージ クラスの主題について何も述べていないようです。標準の適切なセクションへのポインターは高く評価されます。)

4

1 に答える 1

6

[lex.ext] から:

L がuser-defined-string-literal の場合、strud-suffixを除いたリテラルとし、lenをstr内のコード単位の数(つまり、終端の null 文字を除いた長さ) とします。リテラルは、次の形式の呼び出しとして扱われます。L

operator "" X (str , len )

[lex.string] から:

string-literalを評価すると、静的ストレージ durationを持つ文字列リテラル オブジェクトが生成され、上記で指定された文字から初期化されます。

そう:

"hello"_string;

次と同等です。

operator "" _string("hello", 5)

string-literalと同様に"hello"、静的な保存期間があるため、ダングリング ポインターはありません。

于 2015-09-18T12:43:42.097 に答える