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ć?


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


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.


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.


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:


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.


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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.