ISO C90 запрещает смешанные декларации и код в C


83

Я объявил переменную таким образом:

Получаю предупреждение:

ISO C90 запрещает смешанные декларации и код

Как я могу это исправить?


2
Это похоже на GCC -pedanticили -std=c89, и в этом случае вы можете скомпилировать, -std=gnu99если хотите.
Дитрих Эпп

3
Если вы используете gcc, вы можете указать использование C99, который допускает смешанные объявления и код (флаг -std=c99).
hmjd 08

11
Один из вариантов - прекратить компиляцию по стандарту, которому 22 года, для которого даже была заменена замена.
Стивен Кэнон

5
@StephenCanon, сообщите об этом Microsoft. :)
hmjd 08

2
@hmjd: Microsoft не заинтересована в поставке компилятора C; это, скорее всего, не изменится. К счастью, существует ряд совершенно хороших компиляторов, ориентированных на платформу, поставляемую другими поставщиками.
Стивен Кэнон

Ответы:


127

Я думаю, вам следует переместить объявление переменной в начало блока. Т.е.

к


5
... или откройте новый контекст:{foo(); {int i=0; bar();}}
alk

3
@alk s / context / block Это то, что называется в стандарте C.
Jens

@Johan Kotlinski Но какое это имеет значение?
ocean800,

1
@ ocean800 В спецификации C90 сказано, что у вас не может быть объявлений после не-объявлений в одном блоке.
MM

37

Вплоть до стандарта C99 все объявления должны были стоять перед любыми операторами в блоке:

C99 позволяет смешивать объявления и операторы (например, C ++). Многие компиляторы по- прежнему по умолчанию C89, и некоторые компиляторы (например, от Microsoft) не поддерживают C99 вообще .

Итак, вам нужно будет сделать следующее:

  1. Определите, поддерживает ли ваш компилятор C99 или новее; если это так, настройте его так, чтобы он компилировал C99 вместо C89;

  2. Если ваш компилятор не поддерживает C99 или более позднюю версию, вам нужно будет либо найти другой компилятор, который поддерживает его, либо переписать код, чтобы все объявления располагались перед любыми операторами в блоке.


11

Просто используйте компилятор (или предоставьте ему необходимые аргументы), чтобы он компилировался для более новой версии стандарта C, C99 или C11. Например, для семейства компиляторов GCC это будет -std=c99.


6
Этот ответ в лучшем случае неполный. Это устраняет проблему, но не объясняет, что ее вызвало. Этот ответ исключает ситуации, когда более новый компилятор невозможен (несколько возможных причин ...) или среды сборки, в которых переключение параметров на компилятор, как это, невозможно. Голосование "против", потому что я не могу согласиться, что это "настоящий" ответ.
Эндрю Фаланга

1
В некоторых случаях -std=gnu89используется при компиляции модулей ядра Linux.
cbix

4

Убедитесь, что переменная находится в верхней части блока, и, если вы компилируете ее -ansi-pedantic, убедитесь, что она выглядит так:


Вы по-прежнему можете инициализировать переменную, вы просто не можете разместить код до его объявления.
SS Anne

2

Чтобы определить, что действительно вызывает ошибку, я бы сначала попытался удалить = 0

  • Если произошла ошибка, то, скорее всего, объявление идет после кода.

  • Если ошибок нет, то это может быть связано с флагами принуждения / компиляции C-стандарта ИЛИ ... чем-то еще.

В любом случае объявите переменную в начале текущей области видимости. Затем вы можете инициализировать его отдельно. В самом деле, если эта переменная заслуживает отдельной области видимости - ограничьте ее определение в {}.

Если OP сможет прояснить контекст, то последует более направленный ответ.


1

-Wdeclaration-after-statement минимальный воспроизводимый пример

main.c

Предупредить:

Не предупреждать:

Предупреждение:

Проверено на Ubuntu 16.04, GCC 6.4.0.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.