Синтаксис объявления может быть интерпретирован как объектное объявление или часть объявления функции
Неоднозначный синтаксис объявления происходит, когда не ясно из объявления, предназначаются ли объектное объявление или функция/объявление параметра. Неоднозначность часто упоминается как самый раздражающий синтаксический анализ.
Например, эти объявления неоднозначны:
ResourceType aResource();
Это не сразу понятно, если aResource
является функцией, возвращающей переменную типа ResourceType
или объект типа ResourceType
.
TimeKeeper aTimeKeeper(Timer());
Это не сразу понятно, если aTimeKeeper
является объектом, созданным с безымянным объектом типа Timer
или функция с типом указателя функции без имени как параметр. Указатель функции относится к функции без аргумента, и возвратитесь, вводят Timer
.
В случае неоднозначного объявления Стандарт C++ выбирает определенную интерпретацию синтаксиса. Например:
ResourceType aResource();
aResource
.TimeKeeper aTimeKeeper(Timer());
aTimeKeeper
с параметром без имени типа указателя функции.
Если вы или другой разработчик или рецензент кода ожидаете различную интерпретацию, результаты могут быть неожиданными.
Например, позже вы можете столкнуться с ошибкой компиляции, которую трудно понять. Поскольку интерпретация по умолчанию указывает на объявление функции, если вы используете функцию в качестве объекта, компиляторы могут сообщить об ошибке компиляции. Ошибка компиляции указывает, что преобразование от функции до объекта предпринимается без подходящего конструктора.
Сделайте объявление однозначным. Например, зафиксируйте эти неоднозначные объявления можно следующим образом:
ResourceType aResource();
Объектное объявление:
Если объявление относится к объекту, инициализированному с конструктором по умолчанию, перепишите его как:
ResourceType aResource;
ResourceType aResource{};
Объявление функции:
Если объявление относится к функции, используйте определение типа для функции.
typedef ResourceType(*resourceFunctionType)(); resourceFunctionType aResource;
TimeKeeper aTimeKeeper(Timer());
Объектное объявление:
Если объявление отсылает к объекту aTimeKeeper
, инициализированному с безымянным объектом класса Timer
, добавьте дополнительную пару круглой скобки:
TimeKeeper aTimeKeeper( (Timer()) );
TimeKeeper aTimeKeeper{Timer{}};
Объявление функции:
Если объявление относится к функциональному aTimeKeeper
с параметром без имени типа указателя функции, используйте именованный параметр вместо этого.
typedef Timer(*timerType)(); TimeKeeper aTimeKeeper(timerType aTimer);
Группа: Хорошая практика |
Язык: C++ |
Значение по умолчанию: 'off' |
Синтаксис командной строки:
MOST_VEXING_PARSE |
Влияние: низко |
Find defects (-checkers)
| Improper array initialization
| Non-initialized variable
| Variable shadowing
| Write without a further read