Незаметная синтаксическая ошибка в параметре по умолчанию не обнаружена компилятором - PullRequest
5 голосов
/ 24 июня 2010

Я начал получать сообщение об ошибке «ошибка 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, то получу ожидаемую синтаксическую ошибку для этой строки.

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

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

Ответы [ 2 ]

2 голосов
/ 24 июня 2010

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

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

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

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

1 голос
/ 24 июня 2010

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

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

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

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

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