0

static角かっこの間のand *(省略されたサイズ) を無視すると[]、配列宣言子の構文は次のようになります (C99 TC3 (n1256) 6.7.5 p1; C11 (n1570) 6.7.6 p1 より):

direct-declarator: direct-declarator [ type-qualifier-listopt assignment-expressionopt ] [...]

したがって、次のような宣言

int foo[0,1];

構文エラーですが、

int foo[(0,1)];

許可されます (これは VLA であるため、ブロック スコープで)。

コンマを区切り記号として使用するとあいまいになるため、任意の式が許可されない場合があります。たとえば、関数呼び出しの引数は代入式でなければなりません。しかし、そのようなあいまいさがどのように引き起こされるのかはわかりません。

direct-declarator: direct-declarator [ type-qualifier-listopt expressionopt ]

これは C 言語の厳密なスーパーセットを定義しますか? この文法があいまいな例はありますか?

C89 *)では構文に定数式(条件式) が必要だったため、C99 で VLA を許可するにはこれを変更する必要がありました。しかし、式ではなく代入式変更された理由がわかりません。技術的な理由はありますか?

Gcc (およびおそらく他のコンパイラ) には、C 標準に追加される前に拡張機能として VLA がありました。他の拡張機能との競合も説明になる可能性がありますが、そのような拡張機能については知りません。Gcc 3.0.4 はint a[0,1];(および を使用し-std=gnu89-traditional) 受け入れますが、新しいバージョン (Gcc (Debian) 4.7.2-5 でテスト済み) は受け入れないため、これが原因である可能性は低いと思われます。

私が見る限り、この質問は型名の直接抽象宣言子にも同様に適用されます。

*)この C89 ドラフトによると、3.5.4.

4

1 に答える 1

2

配列境界でカンマ演算子の使用を許可することで生じる曖昧さは確かにありません。委員会がそれを許可しない理由があったことは間違いありませんが、議論に参加していない私たちにとっては、それは憶測にすぎません。

動機の 1 つは、混乱を招かないようにすることだったのではないかと推測しています。他の多くの言語では、コンマで区切られた範囲のリストを使用して多次元配列を宣言できます。これらの言語の 1 つに慣れている人はint a[2,7];、2 次元配列を取得するつもりで簡単に間違って書く可能性があります。コンマ演算子が許可されている場合、7 要素の 1 次元配列が宣言され、エラー メッセージは生成されません。このような配列にインデックスを付けようとしても、エラー メッセージは生成されないため、コンパイラは間違いに気付かず、不幸なことと見なされる可能性があります。

しかし、それはただの勝手な推測です。

于 2015-03-01T03:12:03.600 に答える