web-dev-qa-db-ja.com

C文字列リテラルの最大長がmax char []と異なるのはなぜですか?

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


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

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

Char配列に制限はありません。たぶん

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

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

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

const char* str = "foo";

これに

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

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

17
npostavs

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

(C99では、これらの特定の制限が509文字から4095文字に増加しています。)

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

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

23
Keith Thompson

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

標準の作成者はお尻から509を引き出したと思いますが、これから正式なドキュメントを入手しない限り、知る方法はありません。

文字列リテラルに実際に含めることができる文字数は、コンパイラによって異なります。

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

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

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

5

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

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

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';

結果:segfault! (少なくとも私のプラットフォームでは。)

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

余談ですが、

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

完全に等しい

const char __THE_LITERAL[] = "foo";

ここで=は、代入ではなく配列初期化子として機能します。これは

const char *str = "foo";

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

1
Yakov Shklarov