20

明確化:文字列リテラルを(以下を参照)として書き直すことができることを考えると、const char[]リテラルにsよりも短い最大長を課すことは char[]構文上の不便です。なぜC規格はこれを奨励するのですか?


C89標準には、文字列リテラルの変換制限があります。

文字列リテラルまたはワイド文字列リテラルの509文字(連結後)

char配列に制限はありません。多分

オブジェクト内の32767バイト(ホスト環境のみ)

適用されます(オブジェクトまたはホストされた環境が何を意味するのかわかりません)が、とにかくそれははるかに高い制限です。

私の理解では、文字列リテラルは文字を含むchar配列と同等です。つまり、次のように書き直すことが常に可能です。

const char* str = "foo";

これに

static const char __THE_LITERAL[] = { 'f', 'o', 'o', '\0' };
const char* str = __THE_LITERAL;

では、なぜリテラルにそのような厳しい制限があるのでしょうか。

4

3 に答える 3

23

文字列リテラルの制限は、コンパイル時の要件です。論理ソース行の長さにも同様の制限があります。コンパイラは、固定サイズのデータ​​構造を使用して、ソース行と文字列リテラルを保持する場合があります。

(C99は、これらの特定の制限を509文字から4095文字に増やします。)

一方、オブジェクト(の配列などchar)は実行時に作成できます。制限は、コンパイラの設計ではなく、ターゲットマシンのアーキテクチャによって課される可能性があります。

これらはプログラムに課せられる上限ではないことに注意してください。コンパイラは、有限の制限を課す必要はまったくありません。コンパイラが行の長さに制限を課す場合は、少なくとも509文字または4095文字である必要があります。(ほとんどの実際のコンパイラは、固定制限を課すのではなく、メモリを動的に割り当てます。)

于 2012-07-15T01:26:47.797 に答える
6

ここで説明するように、509文字が文字列の制限であるというわけではなく、ANSI互換性に必要な最小文字です。

標準のメーカーは509という数字をお尻から引き出したと思いますが、これから公式のドキュメントを入手しない限り、私たちが知る方法はありません。

文字列リテラルに実際に含めることができる文字数に関しては、コンパイラに依存します。

ここではいくつかの例を示します。

  • MSVC:2048
  • GCC:制限なし(最大100,000文字)。ただし、510文字の後に警告が表示されます。

    長さ100000の文字列リテラルが、C90コンパイラがサポートする必要のある最大長509を超えています

于 2012-07-15T01:25:55.880 に答える
2

回答が遅れて申し訳ありませんが、2つのケースの違いを説明したいと思います(リチャードJ.ロスはすでに同等ではないと指摘しています)。

これを試してみてください:

const char __THE_LITERAL[] = { 'f', 'o', 'o', '\0' };
const char* str = __THE_LITERAL;
char *str_writable = (char *) str;  // Not so const anymore
str_writable[0] = 'g';

str「goo」が含まれるようになりました。

しかし、これを行う場合:

const char* str = "foo";
char *str_writable = (char *) str;
str_writable[0] = 'g';

結果:セグメンテーション違反!(少なくとも私のプラットフォームでは。)

基本的な違いは次のとおりです。最初のケースでは「foo」に初期化された配列がありますが、2番目のケースでは実際の文字列リテラルがあります。

ちなみに、

const char __THE_LITERAL[] = { 'f', 'o', 'o', '\0' };

とまったく同じです

const char __THE_LITERAL[] = "foo";

ここでは=、割り当てとしてではなく、配列初期化子として機能します。これはとは大きく異なります

const char *str = "foo";

ここで、文字列リテラルのアドレスはに割り当てられstrます。

于 2013-01-18T09:47:07.553 に答える