Синтаксис объявления можно интерпретировать как объявление объекта или как часть объявления функции
Этот дефект возникает, когда из описания не ясно, предназначено ли объявление объекта или описание функции/параметра. Неоднозначность часто называют наиболее странным разбором.
Например, эти объявления неоднозначны:
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++ |
| По умолчанию: Откл. |
Синтаксис командной строки:
MOST_VEXING_PARSE |
| Воздействие: Низкий |
Find defects (-checkers) | Improper array initialization | Non-initialized variable | Variable shadowing | Write without a further read