CERT C++: EXP52-CPP

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

Описание

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

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

Реализация Polyspace

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

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

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

Примеры

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

Проблема

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

Шашка не рассматривает волатильные обращения и вызовы функций как потенциальные побочные эффекты.

Риск

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

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

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

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

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

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

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

Для образца вместо:

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. Поскольку выражение не оценивается, изменение не происходит. The 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 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

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

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