Тонкая синтаксическая ошибка в параметре по умолчанию, не пойманном компилятором

Я начал получать ошибку, "ошибка C2059: синтаксическая ошибка: 'параметр по умолчанию'" для строки кода, которая объявила функцию с аргументом строки, которому дали параметр по умолчанию. Это было очевидно немного печально, поскольку сообщение об ошибке точно не просвещало (я знаю, что это - 'параметр по умолчанию'!), и точное объявление работал бы в другом месте.

После смещения об объявлении немного, я нашел, что его положение в его содержании класса на самом деле имело эффект. Сужая его, я нашел, что объявлял другую функцию несколько ошибочно включением точки с запятой после одного из ее параметров по умолчанию. Компилятор казался превосходным с этим, которое казалось немного нечетным. Я занялся расследованиями немного больше и придумал следующий тестовый сценарий, чтобы попытаться выяснить сущность того, что продолжалось:

enum TestEnum1
{
   TEST_ONE
};
class TestClass
{
public:
   enum TestEnum2
   {
      TEST_TWO,
      TEST_THREE,
      TEST_FOUR
   };
   void Func1( int iParm = TEST_ONE; ); // additional semicolon here
   void Func2( std::string strParm = "" );
};

Как код выше стендов, Func2 произведет ошибку компиляции, которую я упомянул выше. Если я перемещаю Func2 выше Func1, то все компилирует прекрасный.

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

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

Я просто пропускаю что-то полностью? Это - ожидаемое поведение? Я не решаюсь идти, называя это ошибкой в компиляторе, конечно, но это едва кажется корректным. Если бы это - просто я неправильно понимающий что-то о стандарте, то я хотел бы знать, где я неправ.

5
задан Georg Fritzsche 23 June 2010 в 20:31
поделиться

2 ответа

Согласен с @tlayton. Я сам немного занимался парсерами и могу подтвердить, что создание хороших сообщений об ошибках для синтаксических ошибок, которые сбивают парсер с толку, может быть очень трудным делом.

Однако этот конкретный случай близок к дефекту. Ирония заключается в том, что в VS2010 компилятор все еще выдает то же самое паршивое сообщение об ошибке, но синтаксический анализатор IntelliSense действительно ловит его:

3   IntelliSense: expected a ')'    c:\projects\cpptemp14\cpptemp14.cpp 20  36  cpptemp14

Это ошибка. Вы можете сообщить об этом на connect.microsoft.com. Дайте мне знать, если вы не хотите тратить на это время, я сообщу об этом (по долгу MVP).

1
ответ дан 15 December 2019 в 06:14
поделиться

Я бы сказал, что это не совсем ошибка в компиляторе, а в том, что неспособность компилятора анализировать код выражается неожиданным образом.

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

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

Поскольку это поведение зависит от конкретного используемого процесса синтаксического анализа, оно зависит от компилятора. Однако, хотя это часто может изменить тип вызываемой ошибки и место, обычно это какая-то ошибка для каждого компилятора.

2
ответ дан 15 December 2019 в 06:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: