質問
プログラムに複数の同一の文字列定数があります:
const char* Ok()
{
return "Ok";
}
int main()
{
const char* ok = "Ok";
}
それらが同じアドレスを持っているという保証はありますか?つまり、次のコードを書くことができますか? GNU C ++は文字列を最適化して同じアドレスを持っていると聞きましたが、プログラムでその機能を使用できますか?
int main()
{
const char* ok = "Ok";
if ( ok == Ok() ) // is it ok?
;
}
解決
確かに保証はありませんが、それは一般的な(私が思うに)最適化です。
C ++標準では(2.13.4 / 2" String literals):
すべての文字列リテラルが異なる(つまり、重複しないオブジェクトに格納される)かどうかは実装定義です。
明確にするために、この最適化が行われることを前提とするコードを書くべきではありません-Chris Lutzが言うように、これに依存するC ++コードは壊れるのを待っているコードです。
他のヒント
これは文字列インターン
と呼ばれますあなたの場合、それに頼らない方が良いです。スコープは異なりますが、私はこのテーマに関して非常に有能だとは思いません
GCCはこのような最適化を使用し、Microsoftは(文字列プーリング)。それは単なる最適化であり、C ++標準では明示的にそれを使用することはできません(2.13.4 / 2)。さらに、他のモジュール/ライブラリから文字列へのポインタを取得することを想像してください-その場合、コンパイラがそのような最適化を行えるとは思いません。
それらが同じアドレスを持っているという保証はありますか?つまり、次のコードを書くことができますか?
文字列リテラルは読み取り専用であるため、標準ではこのような最適化が許可されています。
GNU C ++が文字列を最適化して同じアドレスを持っていると聞いたのですが、プログラムでその機能を使用できますか?
はい、GCC / G ++はよくそうします。私の知る限り、これをオン/オフするオプションがあります。
そのような保証はありません。言語は、彼らが同じアドレスを持っている可能性があるとだけ言っています。または、そうでないかもしれません。
実際には解決策があるので、簡単な解決策があります:
char const * const Message_Ok = "OK";
char const * const OK() { return Message_Ok; }
int main(int argc, const char* argv[])
{
if (OK() == Message_Ok) { std::cout << "OK" << std::endl; }
return 0;
}
2つの異なる文字列リテラルを比較することはできませんが、constグローバル変数を使用して意味を伝え、メモリアドレスを比較するのは OK
です:)
一部のexternが欠落している可能性があります。