ISO C90 zabrania mieszanych deklaracji i kodu w C

83

Zadeklarowałem zmienną w ten sposób:

Otrzymuję ostrzeżenie:

ISO C90 zabrania mieszanych deklaracji i kodu

Jak mogę to naprawić?

Peter Mortensen
źródło
2
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

do

Johan Kotlinski
źródło
5
... 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:

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:

  1. Sprawdź, czy Twój kompilator obsługuje C99 lub nowszy; jeśli tak, skonfiguruj go tak, aby kompilował C99 zamiast C89;

  2. 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.

John Bode
źródło
11

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.

Jens Gustedt
źródło
6
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:

Ron Nuni
źródło
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.

vmsnomad
źródło
1

-Wdeclaration-after-statement minimalny powtarzalny przykład

main.c

Daj ostrzeżenie:

Nie ostrzegaj:

Ostrzeżenie:

Testowano na Ubuntu 16.04, GCC 6.4.0.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
źródło