Синтаксис объявления может быть интерпретирован как объявление объекта или как часть объявления функции
Этот дефект возникает, когда из объявления не ясно, предназначено ли объявление объекта или функции/параметра. Неоднозначность часто упоминается как самый раздражающий анализ.
Для образца эти заявления неоднозначны:
ResourceType aResource();
Не сразу понятно, aResource
ли - функция, возвращающая переменную типа
ResourceType
или объект типа ResourceType
.
TimeKeeper aTimeKeeper(Timer());
Не сразу понятно, aTimeKeeper
ли - объект, созданный с неназванным объектом типа
Timer
или функцию с типом указателя на неназванную функцию в качестве параметра. Указатель на функцию ссылается на функцию без аргументов и возвращаемого типа Timer
.
Проверка не помечает неоднозначные объявления с глобальными возможностями. Например, анализ не помечает объявления с глобальными возможностями, используя формат Type a()
где Type
является типом класса с конструктором по умолчанию. Анализ интерпретирует a
как функция, возвращающая тип Type
.
В случае неоднозначного объявления, Стандарт C++ выбирает конкретную интерпретацию синтаксиса. Для образца:
ResourceType aResource();
aResource
.TimeKeeper aTimeKeeper(Timer());
aTimeKeeper
с неназванным параметром типа указателя на функцию.
Если вы или другой разработчик или рецензент кода ожидаете другой интерпретации, результаты могут оказаться неожиданными.
Например, позже вы можете столкнуться с ошибкой компиляции, которую трудно понять. Поскольку интерпретация по умолчанию указывает на объявление функции, если вы используете функцию в качестве объекта, компиляторы могут сообщить об ошибке компиляции. Ошибка компиляции указывает, что попытка преобразования функции в объект выполняется без подходящего конструктора.
Сделайте заявление однозначным. Например, исправьте эти неоднозначные объявления следующим образом:
ResourceType aResource();
Объявление объекта:
Если объявление относится к объекту, инициализированному конструктором по умолчанию, перепишите его как:
ResourceType aResource;
ResourceType aResource{};
Объявление функции:
Если объявление ссылается на функцию, используйте typedef для функции.
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