ISO C90は、Cでの宣言とコードの混合を禁止しています


83

私はこのように変数を宣言しました:

警告が表示されます:

ISO C90は、宣言とコードの混合を禁止しています

どうすれば修正できますか?


2
GCC-pedanticまたはのように聞こえます。-std=c89その場合は、必要に-std=gnu99応じてコンパイルできます。
ディートリッヒエップ2012年

3
gccを使用している場合は、宣言とコードの混合を許可するC99を使用するように指定できます(フラグ-std=c99)。
hmjd 2012年

11
1つのオプションは、22年前の標準へのコンパイルを停止することです。この標準では、交換品も交換されています。
スティーブンキヤノン

5
@ StephenCanon、Microsoftにそのことを伝えてください。:)
hmjd 2012年

2
@hmjd:MicrosoftはCコンパイラの出荷には関心がありません。それはおそらく変わらないでしょう。幸いなことに、他のベンダーが提供するプラットフォームを対象とした、完全に優れたコンパイラが多数あります。
スティーブンキヤノン

回答:


127

変数宣言をブロックの先頭に移動する必要があると思います。つまり、


5
...または新しいコンテキストを開きます:{foo(); {int i=0; bar();}}
2012年

3
@alk s / context / blockこれがC標準で呼ばれているものです。
イェンス

@Johan Kotlinskiしかし、なぜこれが重要なのですか?
ocean800 2016

1
@ ocean800 C90仕様では、同じブロック内で非宣言の後に宣言を含めることはできないとされています。
MM

37

C99標準までは、すべての宣言はブロック内のステートメントの前に来る必要がありました。

C99では、宣言とステートメント(C ++など)を混在させることができました。多くのコンパイラは依然としてデフォルトでC89に設定されており、一部のコンパイラ(Microsoftなど)はC99をまったくサポートしていません。

したがって、次のことを行う必要があります。

  1. コンパイラがC99以降をサポートしているかどうかを確認します。含まれている場合は、C89ではなくC99をコンパイルするように構成します。

  2. あなたのコンパイラはC99をサポートしていないか、または後で、あなたが必要異なるコンパイラを見つけるためにするか場合はありませんそれをサポートする、またはすべての宣言は、ブロック内の任意のステートメントの前に来るように、あなたのコードを書き換えます。


11

コンパイラを使用して(または必要な引数を指定して)、C標準の最新バージョンであるC99またはC11用にコンパイルします。たとえば、GCCファミリのコンパイラの場合は-std=c99


6
この答えはせいぜい不完全です。問題は修正されますが、原因は説明されていません。この回答は、新しいコンパイラが不可能な状況(いくつかの考えられる理由...)またはこのようなコンパイラへのオプションの切り替えが不可能なビルド環境を除外します。これが「本当の」答えであることに同意できないため、反対票を投じます。
Andrew Falanga 2015

1
場合によって-std=gnu89は、Linuxカーネルモジュールをコンパイルするときに使用されます。
cbix 2017年

4

変数がブロックの上部-ansi-pedanticにあることを確認し、でコンパイルする場合は、次のようになっていることを確認してください。


変数を初期化することはできますが、宣言する前にコードを配置することはできません。
SSアン

2

何が実際にエラーを引き起こすのかを診断するために、私は最初に削除しようとします = 0

  • エラーが発生した場合、宣言はコードの後に​​続く可能性があります。

  • エラーがない場合は、C標準の強制/コンパイルフラグまたは...他の何かに関連している可能性があります。

いずれの場合も、現在のスコープの先頭で変数を宣言します。その後、個別に初期化できます。実際、この変数が独自のスコープに値する場合は、その定義を{}で区切ります。

OPがコンテキストを明確にできる場合は、より指示された応答が続きます。


1

-Wdeclaration-after-statement 最小限の再現可能な例

main.c

警告を与える:

警告を与えないでください:

警告:

Ubuntu 16.04、GCC6.4.0でテスト済み。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.