ISO C90 забороняє змішані декларації та коди на мові C.


83

Я оголосив змінну таким чином:

Я отримую попередження:

ISO C90 забороняє змішані декларації та коди

Як я можу це виправити?


2
Це звучить як GCC -pedanticабо -std=c89, і в цьому випадку ви можете скомпілювати, -std=gnu99якщо хочете.
Дітріх Епп,

3
Якщо ви використовуєте gcc, ви можете вказати використання C99, що дозволяє змішані декларації та код (прапор -std=c99).
hmjd

11
Одним із варіантів було б припинити відповідати стандарту віком 22 роки, на який замінено навіть заміну.
Стівен Канон

5
@StephenCanon, будь ласка, повідомте про це Microsoft. :)
hmjd

2
@hmjd: Microsoft не зацікавлена ​​в доставці компілятора C; це, швидше за все, не зміниться. На щастя, існує цілий ряд чудових компіляторів, націлених на платформу, що постачається іншими постачальниками.
Стівен Канон

Відповіді:


127

Я думаю, вам слід перемістити оголошення змінної до верхньої частини блоку. Тобто

до


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

3
@alk s / context / block Ось як це називається в Стандарті C.
Йенс

@ Джохан Котлінський Але чому це важливо?
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 АБО ... чимось іншим.

У будь-якому випадку оголосіть змінну на початку поточної області дії. Потім ви можете ініціалізувати його окремо. Дійсно, якщо ця змінна заслуговує на власний обсяг - розмежуйте її визначення в {}.

Якби ОП могла пояснити контекст, то слідувала б більш спрямована відповідь.


1

-Wdeclaration-after-statement мінімально відтворюваний приклад

main.c

Попередження:

Не попереджайте:

Попередження:

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.