CERT C++: EXP52-CPP

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

Описание

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

Не используйте побочные эффекты в неоцененном operands.[1]

Реализация Polyspace

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

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

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

Примеры

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

Проблема

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

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

Риск

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

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

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

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

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

Фиксация

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

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

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 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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ОПИСАЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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