CERT C++: DCL52-CPP

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

Описание

Управляйте определением

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

Реализация Polyspace

Это средство проверки проверяет на эти проблемы:

  • Ссылочный тип C++ квалифицирован с const или энергозависимый.

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

Примеры

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

Проблема

Тип Полной ссылки const происходит, когда переменная со ссылочным типом объявляется с 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 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

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

Это программное обеспечение и сопоставленная документация не были рассмотрены, ни являются подтвержденным Университетом Карнеги-Меллон или его Институтом программной инженерии.