exponenta event banner

CERT C++: EXP52-CPP

Не полагайтесь на побочные эффекты в неоцененных операндах

Описание

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

Не полагайтесь на побочные эффекты в неоцененных операндах. [1 ]

Внедрение Polyspace

Эта проверка проверяет следующее:

  • Логический операнд оператора с побочными эффектами

  • sizeof, alignof или decltype операнд с побочными эффектами

Примеры

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

Проблема

Проблема возникает, когда операнд правой руки логического оператора & & или | | содержит побочные эффекты. При оценке выражение с побочным эффектом модифицирует по крайней мере одну из переменных в выражении.

Проверка не рассматривает изменчивые доступы и функциональные вызовы как потенциальные побочные эффекты.

Риск

При оценке выражение с побочным эффектом модифицирует по крайней мере одну из переменных в выражении. Например, n++ - выражение с побочным эффектом.

Правый операнд a:

  • Логичный && оператор вычисляется, только если левый операнд имеет значение true.

  • Логичный || оператор вычисляется, только если левый операнд имеет значение false.

В других случаях правые операнды не оцениваются, поэтому побочные эффекты выражения не имеют места. Если ваша программа полагается на побочные эффекты, вы можете увидеть неожиданные результаты в этих случаях.

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

Если необходимо вычислить выражение в правом операнде, выполните вычисление в отдельном операторе.

Например, вместо:

if(isOK && n++) {}
выполнить операцию в два этапа:
n++;
if(isOK && n) {}

Проблема

Эта проблема возникает, когда sizeof, alignof или decltype оперирует выражением с побочным эффектом. При оценке выражение с побочным эффектом модифицирует по крайней мере одну из переменных в выражении.

Например, средство проверки дефектов не помечает sizeof(n+1) потому что n+1 не изменяет n. Флаги средства проверки sizeof(n++) потому что n++ предназначен для изменения n.

Риск

Побочные эффекты в alignof оператор или decltype оператор не продолжает работу. Выражение в sizeof оператор вычисляется только в том случае, если он необходим для вычисления размера массива переменной длины, например, sizeof(a[n++]).

Если выражение с побочным эффектом не вычисляется, изменение переменной из побочного эффекта не происходит. Если вы полагаетесь на изменение, вы можете увидеть неожиданные результаты.

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

Вычислите выражение с побочным эффектом в отдельном операторе, а затем используйте результат в sizeof, _Alignof, или _Generic оператор.

Например, вместо:

a = sizeof(n++);
выполнить операцию в два этапа:
n++;
a = sizeof(n);

Средство проверки рассматривает вызов функции как выражение с побочным эффектом. Даже если функция не имеет побочных эффектов сейчас, это может иметь побочные эффекты на более поздних дополнениях. Код более удобен для обслуживания при вызове функции за пределами sizeof оператор. При вызове функции в decltypeнапример, чтобы выбрать правильную перегрузку функции и затем определить ее тип возврата, средство проверки рассматривает такой вызов как исключение.

Пример - Оператор приращения в sizeof
#include <stdio.h>

void func(void) {
    unsigned int a = 1U;
    unsigned int b = (unsigned int)sizeof(++a);
    printf ("%u, %u\n", a, b);
}

В этом примере: sizeof работает на ++a, которая предназначена для изменения a. Поскольку выражение не вычисляется, изменение не происходит. printf оператор показывает, что a по-прежнему имеет значение 1.

Коррекция - выполнение приращения снаружи sizeof

Одной из возможных корректировок является сначала выполнение приращения, а затем предоставление результата sizeof оператор.

#include <stdio.h>

void func(void) {
    unsigned int a = 1U;
    ++a;
    unsigned int b = (unsigned int)sizeof (a); 
    printf ("%u, %u\n", a, b);
}

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

Группа: 02. Выражения (EXP)
Представлен в R2019a

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

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

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