web-dev-qa-db-ja.com

代替のforループ構文

以下はC標準のスニペットです( n1256 TC3 C99のセクション6.8.5)。

反復ステートメント:
whileステートメント
doステートメントwhile;
for表現opt; opt; optステートメント
for宣言opt; optステートメント

私の興味をそそるのは、最後のステートメントfor ( declaration expression ; expression ) statementです。 6.8.5.1ではforループについて説明していますが、for ( clause-1 ; expression-2 ; expression-3 ) statement構文についてのみ言及しています。

この構文に従ってコードを記述しようと何度か試みましたが、すべて構文エラーが発生しました。例:

for (int i = 0, i; i++) { /* ... */ }
for (int i = 0; !(i++)) { /* ... */ }

GCC(v4.9.2)を使用してコンパイルすると、すべてerror: expected ‘;’ before ‘)’ tokenと同様のエラーが発生します。

標準を正しい方法で解釈しているかどうかはわかりません。この構文を何らかの便利な方法で使用できますか、それとも何かを見落としていましたか?

34
bzeaman

ご覧のとおり、構文は次のとおりです。

_ for ( declaration expression1opt ; expression2opt ) statement
_

それを一般的なステートメントと比較してみましょう

_ for (int i = 0; i < 10; i++) printf("%d \t", i);
_

ここに、

  • _int i = 0;_はdeclaration [_;_を含む]を示します
  • _i < 10_は_expression1opt_を示します[オプション]
  • _;_は、_;_の構文要件に準拠しています[構文で説明されている必要があります]
  • _i++_は_expression2optprintf("%d \t", i);statementです

さて、あなたの場合、

_for (int i = 0, i; i++) { /* ... */ }
_
  • _int i = 0, i;_はdeclarationを示します
  • _i++_は_expression1opt_を示します
  • _;_ is missing...。

ここでの最後のポイントはエラーを生成します。構文チェックに合格するには、_;_が必要です。

30
Sourav Ghosh

残念ながら、これは読みやすいものではありません。 forステートメントの2番目のケースを読み間違えています。最初のセミコロンはdeclarationの不可欠な部分であるため、目には見えません。付録Aを調べることで、このような構文の質問を簡単に確認できます。

(6.7) declaration: 
    declaration-specifiers init-declarator-listopt ;
    static_assert-declaration
40
Jens Gustedt