AUTOSAR C++14 Rule A8-5-2

Для переменной инициализации следует использовать скобку-инициализацию {} без знака equals

Описание

Определение правила

Для переменной инициализации используется скобка-инициализация {} без знака равенства.

Объяснение

Инициализация скобок:

classType Object{arg1, arg2, ...};
менее неоднозначен, чем другие формы инициализации. Инициализация скобок имеет следующие преимущества:

  • Препятствует неявным преобразованиям сужения, таким как double на float.

  • Избегает неоднозначного синтаксиса, который приводит к проблеме большинства вексинговых анализов.

    Например, из объявления:

    ResourceType aResource();
    Не сразу понятно, aResource ли - функция, возвращающая переменную типа ResourceType или объект типа ResourceType.

    Для получения дополнительной информации смотрите Ambiguous declaration syntax.

Правило также запрещает использование = знак для инициализации, поскольку = может создать впечатление, что вызывается конструктор назначения или копирования, даже если это не так.

Реализация Polyspace

В целом, шашечные флаги инициализируют объект obj1 типа данных Type используя следующие форматы:

  • Type obj1 = obj2;
  • Type obj1(obj2);

Проверка допускает исключение для следующих случаев:

  • Инициализация переменных с типом auto использование простого назначения

  • Инициализация ссылочных типов с помощью простого назначения

  • Объявления с глобальными возможностями с использованием формата Type a() где Type является типом класса с конструктором по умолчанию. Анализ интерпретирует a как функция, возвращающая тип Type.

  • Инициализация переменной цикла в параллельных for OpenMP циклы, то есть в for циклические операторы, которые немедленно следуют #pragma omp parallel for

Проверка включена, только если вы задаете версию C++ C++ 11 или более позднюю. См. C++ standard version (-cpp-version).

Поиск и устранение проблем

Если вы ожидаете нарушения правил, но не видите его, обратитесь к разделу «Стандартные нарушения кодирования не отображаются».

Примеры

расширить все

class ResourceType {
      int memberOne;
      int memberTwo;
    public:
      ResourceType() {memberOne = 0; memberTwo = 0;}
      ResourceType(int m, int n) {memberOne = m; memberTwo = n;}
      ResourceType(ResourceType &anotherResource) {
          memberOne = anotherResource.memberTwo;
          memberTwo = anotherResource.memberOne;
      }
};

void func() {
    ResourceType aResourceOne(); //Noncompliant
    ResourceType aResourceTwo(1, 2); //Noncompliant
    ResourceType aResourceThree = {1,2};   //Noncompliant
     
    ResourceType aResourceFour{1,2}; //Compliant

}

В этом примере функция func объявляет четыре объекта типа ResourceType. Только объявление aResourceFour не нарушает это правило.

Декларации aResourceOne, aResourceTwo и aResourceThree нарушить правило. В частности:

  • Декларация aResourceOne страдает от проблемы большинства vexing parse. Непонятно, aResourceOne ли является объектом типа ResourceType или функция, возвращающая объект типа ResourceType.

  • Декларация aResourceThree кажется, предполагает, что конструктор копирования ResourceType(ResourceType &) вызывается для инициализации. Конструктор копирования инициализирует представитель данных memberOne до 2 и memberTwo по 1. Однако конструктор ResourceType(int, int) вызывается. Этот конструктор инициализирует представитель данных memberOne по 1 и memberTwo к 2.

Проверяйте информацию

Группа: Деклараторы
Категория: Необходимый, Автоматизированный
Введенный в R2019a