Разрешает ли C11 объявления переменных в любом месте функции?

Позволяет ли стандарт C11 (заметьте, я не имею в виду C++11) объявлять переменные в любом месте функции?

Код ниже недействителен в ANSI C (C89, C90):

int main()
{
  printf("Hello world!");
  int a = 5; /* Error: all variables should be declared at the beginning of the function. */
  return 0;
}

Это действительный исходный код в C11?


person Amir Saniyan    schedule 28.10.2012    source источник
comment
Почему недопустим ANSI C? ANSI каким-то образом отказался обновить свой национальный стандарт, чтобы он соответствовал C99?   -  person hmakholm left over Monica    schedule 28.10.2012
comment
Является действительным ANSI C, если вы правильно понимаете, что означает ANSI C. Стандарт ANSI обновляется до самой последней версии. К сожалению, в городском сленге термин ANSI C неправильно приклеился к C 89.   -  person Jens Gustedt    schedule 28.10.2012
comment
@JensGustedt: Альтернативный взгляд на это заключается в том, что ANSI C действительно был C89, но с 1990 года стандартом был ISO C, и ANSI одобрил ISO C в качестве стандарта. Разница между ISO C 90 и ANSI C 89 заключалась в нумерации разделов, AFAIK; в противном случае текст оставался неизменным. Но это расщепление волос. GCC использует -ansi как синоним -std=c89 и не распознает -std=c90 (но большинство версий GCC распознают std=c99, а некоторые последние распознают -std=c11). Раньше для POSIX требовался компилятор c89 C; в настоящее время для этого требуется компилятор c99, поскольку он не был пересмотрен.   -  person Jonathan Leffler    schedule 28.10.2012


Ответы (2)


Да. Это уже было допустимо в C99 (см. второй пункт здесь).

person rubenvb    schedule 28.10.2012

Более менее. C99 представил возможность объявлять переменные в части блока и в первой части цикла for, а C2011 продолжил это.

void c99_or_later(int n, int *x)
{
    for (int i = 0; i < n; i++)  // C99 or later
    {
         printf("x[%d] = %d\n", i, x[i]);
         int t = x[i];           // C99 or later
         x[0] = x[i];
         x[i] = t;
    }
}

Вы также можете заметить, что хвостовые комментарии в стиле C++ допустимы только в C99 или более поздних версиях.

Если вам приходится иметь дело с компиляторами C, несовместимыми с C99 (например, MSVC), то вы не можете использовать эти (удобные) обозначения. GCC предоставляет вам полезный предупреждающий флаг: -Wdeclaration-after-statement.

Обратите внимание, что вы не можете поместить объявление сразу после метки (C11 §6.8 .1 Помеченные операторы); вы не можете пометить объявление или перейти к объявлению. См. также §6.8.2 Составной оператор, §6.7 Объявления и §6.9 Внешние определения. Однако вы можете пометить пустой оператор, так что это не является серьезной проблемой:

label: ;
    int a = 5;
person Jonathan Leffler    schedule 28.10.2012