Это похоже на 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
Я думаю, вам следует переместить объявление переменной в начало блока. Т.е.
... или откройте новый контекст:{foo(); {int i=0; bar();}}
alk
3
@alk s / context / block Это то, что называется в стандарте C.
Jens
@Johan Kotlinski Но какое это имеет значение?
ocean800,
1
@ ocean800 В спецификации C90 сказано, что у вас не может быть объявлений после не-объявлений в одном блоке.
MM
37
Вплоть до стандарта C99 все объявления должны были стоять перед любыми операторами в блоке:
voidfoo(){
int i, j;
double k;
char *c;
// codeif (c)
{
int m, n;
// more code
}
// etc.
}
C99 позволяет смешивать объявления и операторы (например, C ++). Многие компиляторы по- прежнему по умолчанию C89, и некоторые компиляторы (например, от Microsoft) не поддерживают C99 вообще .
Итак, вам нужно будет сделать следующее:
Определите, поддерживает ли ваш компилятор C99 или новее; если это так, настройте его так, чтобы он компилировал C99 вместо C89;
Если ваш компилятор не поддерживает C99 или более позднюю версию, вам нужно будет либо найти другой компилятор, который поддерживает его, либо переписать код, чтобы все объявления располагались перед любыми операторами в блоке.
Просто используйте компилятор (или предоставьте ему необходимые аргументы), чтобы он компилировался для более новой версии стандарта C, C99 или C11. Например, для семейства компиляторов GCC это будет -std=c99.
Этот ответ в лучшем случае неполный. Это устраняет проблему, но не объясняет, что ее вызвало. Этот ответ исключает ситуации, когда более новый компилятор невозможен (несколько возможных причин ...) или среды сборки, в которых переключение параметров на компилятор, как это, невозможно. Голосование "против", потому что я не могу согласиться, что это "настоящий" ответ.
Эндрю Фаланга
1
В некоторых случаях -std=gnu89используется при компиляции модулей ядра Linux.
cbix
4
Убедитесь, что переменная находится в верхней части блока, и, если вы компилируете ее -ansi-pedantic, убедитесь, что она выглядит так:
Вы по-прежнему можете инициализировать переменную, вы просто не можете разместить код до его объявления.
SS Anne
2
Чтобы определить, что действительно вызывает ошибку, я бы сначала попытался удалить = 0
Если произошла ошибка, то, скорее всего, объявление идет после кода.
Если ошибок нет, то это может быть связано с флагами принуждения / компиляции C-стандарта ИЛИ ... чем-то еще.
В любом случае объявите переменную в начале текущей области видимости. Затем вы можете инициализировать его отдельно. В самом деле, если эта переменная заслуживает отдельной области видимости - ограничьте ее определение в {}.
Если OP сможет прояснить контекст, то последует более направленный ответ.
-pedantic
или-std=c89
, и в этом случае вы можете скомпилировать,-std=gnu99
если хотите.-std=c99
).Ответы:
Я думаю, вам следует переместить объявление переменной в начало блока. Т.е.
{ foo(); int i = 0; bar(); }
к
{ int i = 0; foo(); bar(); }
источник
{foo(); {int i=0; bar();}}
Вплоть до стандарта C99 все объявления должны были стоять перед любыми операторами в блоке:
void foo() { int i, j; double k; char *c; // code if (c) { int m, n; // more code } // etc. }
C99 позволяет смешивать объявления и операторы (например, C ++). Многие компиляторы по- прежнему по умолчанию C89, и некоторые компиляторы (например, от Microsoft) не поддерживают C99 вообще .
Итак, вам нужно будет сделать следующее:
Определите, поддерживает ли ваш компилятор C99 или новее; если это так, настройте его так, чтобы он компилировал C99 вместо C89;
Если ваш компилятор не поддерживает C99 или более позднюю версию, вам нужно будет либо найти другой компилятор, который поддерживает его, либо переписать код, чтобы все объявления располагались перед любыми операторами в блоке.
источник
Просто используйте компилятор (или предоставьте ему необходимые аргументы), чтобы он компилировался для более новой версии стандарта C, C99 или C11. Например, для семейства компиляторов GCC это будет
-std=c99
.источник
-std=gnu89
используется при компиляции модулей ядра Linux.Убедитесь, что переменная находится в верхней части блока, и, если вы компилируете ее
-ansi-pedantic
, убедитесь, что она выглядит так:function() { int i; i = 0; someCode(); }
источник
Чтобы определить, что действительно вызывает ошибку, я бы сначала попытался удалить
= 0
Если произошла ошибка, то, скорее всего, объявление идет после кода.
Если ошибок нет, то это может быть связано с флагами принуждения / компиляции C-стандарта ИЛИ ... чем-то еще.
В любом случае объявите переменную в начале текущей области видимости. Затем вы можете инициализировать его отдельно. В самом деле, если эта переменная заслуживает отдельной области видимости - ограничьте ее определение в {}.
Если OP сможет прояснить контекст, то последует более направленный ответ.
источник
-Wdeclaration-after-statement
минимальный воспроизводимый примерmain.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
Предупредить:
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
Не предупреждать:
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
Предупреждение:
main.c: In function ‘main’: main.c:5:5: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] int a = 1; ^~~
Проверено на Ubuntu 16.04, GCC 6.4.0.
источник