Brzmi jak GCC -pedanticlub -std=c89, w takim przypadku, możesz skompilować, -std=gnu99jeśli chcesz.
Dietrich Epp
3
Jeśli używasz gcc, możesz określić użycie C99, który zezwala na mieszane deklaracje i kod (flaga -std=c99).
hmjd
11
Jedną z opcji byłoby zaprzestanie kompilowania do standardu, który ma 22 lata, a nawet zastąpiono go zamiennikiem.
Stephen Canon
5
@StephenCanon, powiedz o tym firmie Microsoft. :)
hmjd
2
@hmjd: Microsoft nie jest zainteresowany dostarczaniem kompilatora C; to prawdopodobnie się nie zmieni. Na szczęście istnieje wiele doskonale dobrych kompilatorów, których celem jest platforma dostarczana przez innych dostawców.
Stephen Canon
Odpowiedzi:
127
Myślę, że powinieneś przenieść deklarację zmiennej na początek bloku. To znaczy
... lub otwórz nowy kontekst:{foo(); {int i=0; bar();}}
alk
3
@alk s / context / block Tak to się nazywa w standardzie C.
Jens,
@Johan Kotlinski Ale dlaczego to ma znaczenie?
ocean800
1
@ ocean800 Specyfikacja C90 mówi, że nie możesz mieć deklaracji po nie-deklaracjach w tym samym bloku.
MM
37
Aż do standardu C99 wszystkie deklaracje musiały występować przed jakimikolwiek instrukcjami w bloku:
voidfoo(){
int i, j;
double k;
char *c;
// codeif (c)
{
int m, n;
// more code
}
// etc.
}
C99 pozwala na mieszanie deklaracji i instrukcji (jak C ++). Wiele kompilatorów nadal domyślnie C89, a niektóre kompilatory (takie jak Microsoft) nie obsługują C99 w ogóle .
Musisz więc wykonać następujące czynności:
Sprawdź, czy Twój kompilator obsługuje C99 lub nowszy; jeśli tak, skonfiguruj go tak, aby kompilował C99 zamiast C89;
Jeśli Twój kompilator nie obsługuje C99 lub nowszego, musisz albo znaleźć inny kompilator, który go obsługuje, albo przepisać kod tak, aby wszystkie deklaracje znajdowały się przed wszelkimi instrukcjami w bloku.
Po prostu użyj kompilatora (lub podaj mu potrzebne argumenty), tak aby kompilował się dla nowszej wersji standardu C, C99 lub C11. Np. Dla rodziny kompilatorów GCC tak będzie -std=c99.
Ta odpowiedź jest w najlepszym razie niepełna. Naprawia problem, ale nie wyjaśnia, co go spowodowało. Ta odpowiedź wyklucza sytuacje, w których nowszy kompilator nie jest możliwy (kilka możliwych powodów ...) lub środowiska kompilacji, w których przełączanie opcji na kompilator w ten sposób nie jest możliwe. Głos negatywny, ponieważ nie mogę się zgodzić, to jest „prawdziwa” odpowiedź.
Andrew Falanga
1
W niektórych przypadkach -std=gnu89jest używany podczas kompilacji modułów jądra Linuksa.
cbix
4
Upewnij się, że zmienna znajduje się w górnej części bloku, a na wypadek, gdybyś ją kompilował -ansi-pedantic, upewnij się, że wygląda następująco:
Nadal możesz zainicjować zmienną, po prostu nie możesz umieścić kodu przed jego zadeklarowaniem.
SS Anne
2
Aby zdiagnozować, co naprawdę powoduje błąd, najpierw spróbuję usunąć = 0
Jeśli błąd zostanie wyzwolony, najprawdopodobniej deklaracja nastąpi po kodzie.
Jeśli nie ma błędu, może to być związane z flagami wymuszania / kompilacji standardu C LUB ... czymś innym.
W każdym razie zadeklaruj zmienną na początku bieżącego zakresu. Możesz następnie zainicjować go osobno. Rzeczywiście, jeśli ta zmienna zasługuje na swój własny zakres - ogranicz jej definicję w {}.
Gdyby PO mógł wyjaśnić kontekst, nastąpiłaby bardziej ukierunkowana reakcja.
-pedantic
lub-std=c89
, w takim przypadku, możesz skompilować,-std=gnu99
jeśli chcesz.-std=c99
).Odpowiedzi:
Myślę, że powinieneś przenieść deklarację zmiennej na początek bloku. To znaczy
{ foo(); int i = 0; bar(); }
do
{ int i = 0; foo(); bar(); }
źródło
{foo(); {int i=0; bar();}}
Aż do standardu C99 wszystkie deklaracje musiały występować przed jakimikolwiek instrukcjami w bloku:
void foo() { int i, j; double k; char *c; // code if (c) { int m, n; // more code } // etc. }
C99 pozwala na mieszanie deklaracji i instrukcji (jak C ++). Wiele kompilatorów nadal domyślnie C89, a niektóre kompilatory (takie jak Microsoft) nie obsługują C99 w ogóle .
Musisz więc wykonać następujące czynności:
Sprawdź, czy Twój kompilator obsługuje C99 lub nowszy; jeśli tak, skonfiguruj go tak, aby kompilował C99 zamiast C89;
Jeśli Twój kompilator nie obsługuje C99 lub nowszego, musisz albo znaleźć inny kompilator, który go obsługuje, albo przepisać kod tak, aby wszystkie deklaracje znajdowały się przed wszelkimi instrukcjami w bloku.
źródło
Po prostu użyj kompilatora (lub podaj mu potrzebne argumenty), tak aby kompilował się dla nowszej wersji standardu C, C99 lub C11. Np. Dla rodziny kompilatorów GCC tak będzie
-std=c99
.źródło
-std=gnu89
jest używany podczas kompilacji modułów jądra Linuksa.Upewnij się, że zmienna znajduje się w górnej części bloku, a na wypadek, gdybyś ją kompilował
-ansi-pedantic
, upewnij się, że wygląda następująco:function() { int i; i = 0; someCode(); }
źródło
Aby zdiagnozować, co naprawdę powoduje błąd, najpierw spróbuję usunąć
= 0
Jeśli błąd zostanie wyzwolony, najprawdopodobniej deklaracja nastąpi po kodzie.
Jeśli nie ma błędu, może to być związane z flagami wymuszania / kompilacji standardu C LUB ... czymś innym.
W każdym razie zadeklaruj zmienną na początku bieżącego zakresu. Możesz następnie zainicjować go osobno. Rzeczywiście, jeśli ta zmienna zasługuje na swój własny zakres - ogranicz jej definicję w {}.
Gdyby PO mógł wyjaśnić kontekst, nastąpiłaby bardziej ukierunkowana reakcja.
źródło
-Wdeclaration-after-statement
minimalny powtarzalny przykładmain.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
Daj ostrzeżenie:
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
Nie ostrzegaj:
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
Ostrzeżenie:
main.c: In function ‘main’: main.c:5:5: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] int a = 1; ^~~
Testowano na Ubuntu 16.04, GCC 6.4.0.
źródło