Неожиданная ошибка компиляции для тривиального кода - PullRequest
1 голос
/ 09 сентября 2011

Я столкнулся со странной ошибкой компилятора (при использовании VC2010) при попытке скомпилировать библиотеку (flextGL), что для меня абсолютно бессмысленно.

Рассмотрим следующий минимальный пример C (test.c):

void a()
{
    // ...
}

int b()
{
    a();

    int c;

    return 0;
}

Если я пытаюсь скомпилировать это под VC2010, я получаю следующую ошибку:

test.c(10) : error C2143: syntax error : missing ';' before 'type'

Ошибка относится к строке int c;.

После некоторых экспериментов я также обнаружил следующее:

  • Если я удаляю строку int c;, она прекрасно компилируется.
  • Если я удаляю строку a();, она прекрасно компилируется.
  • Если я переместу строку int c; над строкой a();, она будет хорошо скомпилирована.
  • Если я переименую файл для компиляции в C ++ вместо C (.cpp вместо .c), он скомпилируется нормально.

Почему происходит эта странная ошибка?

Мое единственное предположение - это одна из тех архаичных особенностей C, где все переменные должны быть объявлены в верхней части функции. Но я бы подумал, что современные компиляторы умнее этого.

Ответы [ 5 ]

5 голосов
/ 09 сентября 2011

Ваше предположение верно.

Вы объявили переменную после объявления переменной в блоке.Visual C ++ не реализует C99, а только ANSI C, поэтому не компилируется.

4 голосов
/ 09 сентября 2011

Компилятор C, включенный в VC2010, взят из более старой версии стандарта, в которой переменные могут быть объявлены только в верхней части области видимости.

1 голос
/ 09 сентября 2011

С включенными gcc и предупреждениями я получаю:

gcc -Wall --pedantic foo.c -c 
foo.c:3:5: warning: C++ style comments are not allowed in ISO C90
foo.c:3:5: warning: (this will be reported only once per input file)
foo.c: In function ‘b’:
foo.c:10: warning: ISO C90 forbids mixed declarations and code
foo.c:10: warning: unused variable ‘c’

Возможно, вам следует включить все предупреждения для вашего компилятора, чтобы получить больше информации.

1 голос
/ 09 сентября 2011

Поскольку вы компилируете с Visual C ++, а Microsoft не поддерживает C99. Он поддерживает C89, что означает, что вы должны объявить все переменные в верхней части области видимости.

0 голосов
/ 09 сентября 2011

В C все переменные должны быть объявлены в начале блока. Память для переменных (в вашем случае 4 байта) добавляется в стек при вводе новой функции и удаляется при выходе из функции.

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

int b()  
{  
   a();  

   {
   int c;  
   }

   return 0;  
}  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...