Es klingt wie GCCs -pedanticoder -std=c89, in welchem Fall Sie kompilieren können, -std=gnu99wenn Sie möchten.
Dietrich Epp
3
Wenn Sie gcc verwenden, können Sie angeben, dass C99 verwendet werden soll, das gemischte Deklarationen und Code (Flag -std=c99) zulässt .
hmjd
11
Eine Möglichkeit wäre, die Kompilierung auf einen 22 Jahre alten Standard zu beenden, für den sogar der Ersatz ersetzt wurde.
Stephen Canon
4
@ StephenCanon, bitte sagen Sie Microsoft das. :)
hmjd
2
@hmjd: Microsoft hat kein Interesse daran, einen C-Compiler zu liefern. das wird sich wahrscheinlich nicht ändern. Glücklicherweise gibt es eine Reihe perfekter Compiler, die auf die von anderen Anbietern bereitgestellte Plattform abzielen.
Stephen Canon
Antworten:
124
Ich denke, Sie sollten die Variablendeklaration an den Anfang des Blocks verschieben. Dh
... oder eröffnen Sie einen neuen Kontext:{foo(); {int i=0; bar();}}
Alk
3
@alk s / context / block So heißt es im C-Standard.
Jens
@ Joan Kotlinski Aber warum ist das wichtig?
ocean800
1
@ ocean800 Die C90-Spezifikation besagt, dass Sie keine Deklarationen nach Nichtdeklarationen im selben Block haben können.
MM
37
Bis zum C99-Standard mussten alle Deklarationen vor Aussagen in einem Block stehen:
voidfoo(){
int i, j;
double k;
char *c;
// codeif (c)
{
int m, n;
// more code
}
// etc.
}
C99 erlaubt das Mischen von Deklarationen und Anweisungen (wie C ++). Viele Compiler verwenden immer noch standardmäßig C89, und einige Compiler (z. B. Microsoft) unterstützen C99 überhaupt nicht .
Sie müssen also Folgendes tun:
Stellen Sie fest, ob Ihr Compiler C99 oder höher unterstützt. Wenn dies der Fall ist, konfigurieren Sie es so, dass C99 anstelle von C89 kompiliert wird.
Wenn Ihr Compiler C99 oder höher nicht unterstützt, müssen Sie entweder einen anderen Compiler finden, der dies unterstützt, oder Ihren Code neu schreiben, sodass alle Deklarationen vor Anweisungen innerhalb des Blocks stehen.
Verwenden Sie einfach einen Compiler (oder geben Sie ihm die erforderlichen Argumente), damit er für eine neuere Version des C-Standards C99 oder C11 kompiliert wird. Zum Beispiel für die GCC-Compilerfamilie -std=c99.
Diese Antwort ist bestenfalls unvollständig. Es behebt das Problem, erklärt aber nicht, was es verursacht hat. Diese Antwort schließt Situationen aus, in denen ein neuerer Compiler nicht möglich ist (mehrere mögliche Gründe ...) oder Umgebungen zu erstellen, in denen ein Wechsel der Optionen zum Compiler wie dieser nicht möglich ist. Eine Abwertung, weil ich nicht zustimmen kann, ist die "echte" Antwort.
Andrew Falanga
1
In einigen Fällen -std=gnu89wird beim Kompilieren von Linux-Kernelmodulen verwendet.
cbix
4
Stellen Sie sicher, dass sich die Variable im oberen Teil des Blocks befindet, und stellen Sie beim Kompilieren -ansi-pedanticFolgendes sicher:
Sie können die Variable weiterhin initialisieren. Sie können nur keinen Code platzieren, bevor Sie ihn deklarieren.
SS Anne
2
Um zu diagnostizieren, was den Fehler wirklich auslöst, würde ich zuerst versuchen, ihn zu entfernen = 0
Wenn der Fehler ausgelöst wird, folgt die Deklaration höchstwahrscheinlich dem Code.
Wenn kein Fehler vorliegt, kann dies mit einem C-Standard für Durchsetzungs- / Kompilierungsflags oder ... etwas anderem zusammenhängen.
In jedem Fall deklarieren Sie die Variable am Anfang des aktuellen Bereichs. Sie können es dann separat initialisieren. Wenn diese Variable ihren eigenen Gültigkeitsbereich verdient, begrenzen Sie ihre Definition in {}.
Wenn das OP den Kontext klären könnte, würde eine gezieltere Antwort folgen.
-pedantic
oder-std=c89
, in welchem Fall Sie kompilieren können,-std=gnu99
wenn Sie möchten.-std=c99
) zulässt .Antworten:
Ich denke, Sie sollten die Variablendeklaration an den Anfang des Blocks verschieben. Dh
{ foo(); int i = 0; bar(); }
zu
{ int i = 0; foo(); bar(); }
quelle
{foo(); {int i=0; bar();}}
Bis zum C99-Standard mussten alle Deklarationen vor Aussagen in einem Block stehen:
void foo() { int i, j; double k; char *c; // code if (c) { int m, n; // more code } // etc. }
C99 erlaubt das Mischen von Deklarationen und Anweisungen (wie C ++). Viele Compiler verwenden immer noch standardmäßig C89, und einige Compiler (z. B. Microsoft) unterstützen C99 überhaupt nicht .
Sie müssen also Folgendes tun:
Stellen Sie fest, ob Ihr Compiler C99 oder höher unterstützt. Wenn dies der Fall ist, konfigurieren Sie es so, dass C99 anstelle von C89 kompiliert wird.
Wenn Ihr Compiler C99 oder höher nicht unterstützt, müssen Sie entweder einen anderen Compiler finden, der dies unterstützt, oder Ihren Code neu schreiben, sodass alle Deklarationen vor Anweisungen innerhalb des Blocks stehen.
quelle
Verwenden Sie einfach einen Compiler (oder geben Sie ihm die erforderlichen Argumente), damit er für eine neuere Version des C-Standards C99 oder C11 kompiliert wird. Zum Beispiel für die GCC-Compilerfamilie
-std=c99
.quelle
-std=gnu89
wird beim Kompilieren von Linux-Kernelmodulen verwendet.Stellen Sie sicher, dass sich die Variable im oberen Teil des Blocks befindet, und stellen Sie beim Kompilieren
-ansi-pedantic
Folgendes sicher:function() { int i; i = 0; someCode(); }
quelle
Um zu diagnostizieren, was den Fehler wirklich auslöst, würde ich zuerst versuchen, ihn zu entfernen
= 0
Wenn der Fehler ausgelöst wird, folgt die Deklaration höchstwahrscheinlich dem Code.
Wenn kein Fehler vorliegt, kann dies mit einem C-Standard für Durchsetzungs- / Kompilierungsflags oder ... etwas anderem zusammenhängen.
In jedem Fall deklarieren Sie die Variable am Anfang des aktuellen Bereichs. Sie können es dann separat initialisieren. Wenn diese Variable ihren eigenen Gültigkeitsbereich verdient, begrenzen Sie ihre Definition in {}.
Wenn das OP den Kontext klären könnte, würde eine gezieltere Antwort folgen.
quelle
-Wdeclaration-after-statement
minimal reproduzierbares BeispielHaupt c
#!/usr/bin/env bash set -eux cat << EOF > main.c #include <stdio.h> int main(void) { puts("hello"); int a = 1; printf("%d\n", a); return 0; } EOF
Warnung geben:
gcc -std=c89 -Wdeclaration-after-statement -Werror main.c gcc -std=c99 -Wdeclaration-after-statement -Werror main.c gcc -std=c89 -pedantic -Werror main.c
Keine Warnung geben:
gcc -std=c89 -pedantic -Wno-declaration-after-statement -Werror main.c gcc -std=c89 -Wno-declaration-after-statement -Werror main.c gcc -std=c99 -pedantic -Werror main.c gcc -std=c89 -Wall -Wextra -Werror main.c # https://stackoverflow.com/questions/14737104/what-is-the-default-c-mode-for-the-current-gcc-especially-on-ubuntu/53063656#53063656 gcc -pedantic -Werror main.c
Die Warnung:
main.c: In function ‘main’: main.c:5:5: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] int a = 1; ^~~
Getestet unter Ubuntu 16.04, GCC 6.4.0.
quelle