Синтаксис объявления может быть интерпретирован как объявление объекта или как часть объявления функции
Этот дефект возникает, когда из объявления не ясно, предназначено ли объявление объекта или функции/параметра. Неоднозначность часто упоминается как самый раздражающий анализ.
Для образца эти заявления неоднозначны:
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