2013-07-28 6 views
14

コンパイル時のCのような文字列は、スタティックメモリ内に1つのインスタンスとして保持されます。例えば、gcc 4.6の実行例では、私はtrueの両方を以下のように実行しています。しかし、私はそれが常に真実であり、移植可能であるのだろうかと思います。 CとC++の両方の動作は面白いです。スタティックメモリインスタンス内の文字列数

#include <iostream> 

bool amIportable(const char* value) { 
    const char* slocal = "Hello"; 
    return (slocal==value); 
} 

int main() { 
    const char* s = "Hello"; 
    std::cout << std::boolalpha 
      << amIportable(s) << '\n' 
      << amIportable("Hello") << '\n'; 
} 

答えて

12

いいえ、これは必ずしも真実ではなく、移植性もありません。

同じ文字列リテラルをマージすることは、コンパイラとリンカーが連携して行う最適化です。特定の最適化スイッチが設定されている場合にのみ、GCCとMicrosoftのコンパイラの両方の最新バージョンがそれをサポートしています。

「オン」または「オフ」の機能だけではありません。異なるコンパイラと異なる最適化設定は、が積極的にの実行方法に影響を与えます。たとえば、文字列リテラルは、個々の関数の範囲内でのみプールされることもあります。また、翻訳単位のレベルで発生することもあります。また、リンカーが複数の翻訳単位にまたがる場合もあります。

これは、CおよびC++標準ではこの動作が実装依存であるために許可されています。

9

いいえ、実装はCとC++の両方に依存します。

C11§6.4.5/ 7 文字列リテラル

これらの配列は、それらの要素が適切な値を持って提供異なっているかどうかが指定されていません。プログラムがそのような配列を変更しようとすると、動作は未定義です。

C++ 11§2.14.5/ 12 文字列リテラル

すべての文字列リテラルは、別個であるかどうか(つまり、重複しないオブジェクトに格納されている)実装定義です。文字列リテラルを変更しようとすると、定義されません。

2

しかし、私は疑問に思うことは常に真

ではありません、少なくともCの標準のような何か「二つの同一の文字列リテラルは同じ配列に格納されているかどうかは、実装定義である」と言います。

2

に同じ値を持つ2つの異なる文字列リテラルを比較しています。 C++標準によれば、同一の文字列リテラルが同じメモリを占有しているかどうかを定義した の実装が定義されています(これは実装が の内容でなければならないことを意味します)。 C標準によれば、それは である。 (私はC++の標準では、文字列 のリテラルが であれば同じインスタンスを共有し、それ以外の場合は同じ インスタンスを共有していないことを、C++標準で実現することができます。リテラル文字列を返す)

あなたの目標は、ポインタを単に比較することができるのであれば、通常の ソリューションは、それがクラスのメンバである場合、関数(スタティックを使用することです) :

char const* 
value() 
{ 
    return "Hello"; 
} 

bool 
isHello(char const* str) 
{ 
    return str == valule; 
} 

と文字列のすべてのインスタンスが value()を呼び出して取得されていることを確認します。

関連する問題