1. ホーム
  2. c++

[解決済み] なぜ一部のコンパイラは同一の文字列リテラルに同一のアドレスを使用するのですか?

2023-02-12 14:21:55

疑問点

https://godbolt.org/z/cyBiWY

私は、2つの 'some' リテラルが見えますが、clangとgccでは1つだけです。これは、コード実行の結果がまったく異なることにつながります。

static const char *A = "some";
static const char *B = "some";

void f() {
    if (A == B) {
        throw "Hello, string merging!";
    }
}

これらのコンパイル出力の違いと類似点を説明できる人はいますか?なぜ clang/gcc は最適化が要求されていないにもかかわらず、何かを最適化するのでしょうか? これはある種の未定義の動作なのでしょうか?

私はまた、宣言を以下に示すものに変更した場合、clang/gcc/msvcは何も残さないことに気づきました。 "some" を全く残しません。なぜ動作が違うのでしょうか?

static const char A[] = "some";
static const char B[] = "some";

どのように解決するのですか?

これは未定義の動作ではなく、未指定の動作です。例えば 文字列リテラル ,

コンパイラは、等しいまたは重複する文字列リテラルに対してストレージを結合することができますが、必須ではありません。つまり、同一の文字列リテラルは、ポインターで比較されたときに等しく比較されるかもしれないし、されないかもしれません。

の結果を意味します。 A == Btrue または false に依存してはいけません。

規格から [lex.文字列]/16 :

<ブロッククオート

すべての文字列リテラルが区別できるかどうか(つまり、重ならないオブジェクトに格納されるかどうか)、文字列リテラルの連続した評価が同じオブジェクトをもたらすか異なるオブジェクトをもたらすかは、特定されません。