exponenta event banner

CERT C++: DCL52-CPP

Никогда не квалифицируйте ссылочный тип с const или volatile

Описание

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

Никогда не относите ссылочный тип к категории const или volatile. [1 ]

Внедрение Polyspace

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

  • Эталонный тип C++, квалифицированный как const или volatile.

  • C++ ссылка на конст-квалифицированный тип с последующей модификацией.

Примеры

развернуть все

Проблема

const-Qualified Reference Type возникает, когда переменная со ссылочным типом объявлена с помощью const или volatile квалификатор, например:

char &const c;

Риск

Стандарт C++ 14 гласит, чтоconst или volatile квалифицированные ссылки плохо сформированы (если только они не введены через typedef, в этом случае они игнорируются). Например, ссылка на одну переменную не может быть сделана для ссылки на другую переменную. Следовательно, использование const квалификатор не требуется для переменной со ссылочным типом.

Часто использование этих квалификаторов указывает на ошибку кодирования. Например, вы хотели объявить ссылку на const-квалифицированный тип:

char const &c;
но вместо этого объявлен const- квалифицированная ссылка:
char &const c;
Если компилятор не обнаруживает ошибку, можно увидеть неожиданные результаты. Например, вы можете ожидать c быть неизменным, но видеть другое значение c сравнивают с его значением при объявлении.

Зафиксировать

Посмотрите, если const или volatile квалификатор размещен неправильно. Например, посмотрите, хотите ли вы сослаться на const- квалифицированный тип и введено:

char &const c;
вместо:
char const &c;
Если квалификатор размещен неправильно, исправьте ошибку. Разместить const или volatileквалификатор перед & оператор. В противном случае удалите избыточный квалификатор.

Пример - const- Квалифицированный тип ссылки
int func (int &const iRef) {
    iRef++;
    return iRef%2;
}

В этом примере: iRef является const- квалифицированный тип ссылки. С тех пор iRef не может ссылаться на другую переменную, const квалификатор избыточен.

Исправление - Удалить const Определитель

Удалите резервированную const квалификатор. С тех пор iRef изменен в func, оно не предназначено для обозначения const-квалифицированная переменная. Перемещение const квалификатор перед & приведет к ошибке компиляции.

int func (int &iRef) {
    iRef++;
    return iRef%2;
}
Исправление - Фиксация размещения const Определитель

Если вы не идентифицируете для изменения iRef в func, объявить iRef как ссылка на const-квалифицированная переменная. Разместить const квалификатор перед & оператор. Убедитесь, что вы не изменяете iRef в func.

int func (int const &iRef) {
    return (iRef+1)%2;
}
Проблема

Этот дефект возникает, когда переменная ссылается на const-квалифицированный тип изменяется после объявления.

Например, в этом примере refVal имеет тип const int &, но его значение изменяется в последующем операторе.

using constIntRefType = const int &;
void func(constIntRefType refVal, int val){
   ...
   refVal = val; //refVal is modified
   ...
}

Риск

const квалификатор ссылочного типа подразумевает, что переменная типа инициализируется при объявлении и впоследствии не изменяется.

Компиляторы могут обнаруживать изменения ссылок на const-квалифицированные типы как ошибка компиляции. Если компилятор не обнаруживает ошибку, поведение не определено. Polyspace ® помечает этот дефект независимо от ошибки компиляции.

Зафиксировать

Избегайте изменения const-квалифицированные типы ссылок. Если требуется изменение, удалите const квалификатор из описания ссылочного типа.

Пример - Изменение const-квалифицированные типы ссылок
typedef const int cint;           
typedef cint& ref_to_cint;       

void func(ref_to_cint refVal, int initVal){
   refVal = initVal;
}

В этом примере: ref_to_cint является ссылкой на const-квалифицированный тип. Переменная refVal типа ref_to_cint должен быть инициализирован, когда func вызывается и впоследствии не изменяется. Изменение нарушает договор, подразумеваемый const квалификатор.

Исправление - Избежать изменения const-квалифицированные типы ссылок

Одна из возможных корректировок заключается в том, чтобы избежать const в объявлении ссылочного типа.

typedef int& ref_to_int;       

void func(ref_to_int refVal, int initVal){
   refVal = initVal;
}

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

Группа: 01. Объявления и инициализация (DCL)
Представлен в R2019a

[1] Данное программное обеспечение было создано компанией MathWorks и включает в себя следующие компоненты: «Веб-сайт SEI CERT-C», © 2017 Университет Карнеги-Меллон, веб-сайт SEI CERT-C + + © 2017 Университет Карнеги-Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги-Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги-Меллон, со специальным разрешением от его Института программного обеспечения.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОНА И/ИЛИ ЕГО ПРОГРАММНОГО ИНЖЕНЕРНОГО ИНСТИТУТА, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ КАК ЕСТЬ. УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБЫХ ВОПРОСОВ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИИ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ ТОВАРНОЙ ПРИГОДНОСТИ, ИСКЛЮЧИТЕЛЬНОСТИ ИЛИ РЕЗУЛЬТАТОВ, ПОЛУЧЕННЫХ ОТ ИСПОЛЬЗОВАНИЯ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

Данное программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллона или его Институтом разработки программного обеспечения.