CERT C: Rule EXP44-C

Не полагайтесь на побочные эффекты в операндах до размеров, _Alignof или _Generic

Описание

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

Не полагайтесь на побочные эффекты в операндах до размеров, _Alignof или _Generic.[1]

Реализация Polyspace

Эта проверка проверяет, проигнорирован ли побочный эффект выражения.

Примеры

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

Проблема

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

Для образца проверка дефекта не помечается sizeof(n+1) потому что n+1 не изменяет n. Шашечные флаги sizeof(n++) потому что n++ предназначен для изменения n.

Проверка также применяется к оператору C++ alignof и его расширения C, __alignof__ и __typeof__.

Риск

Выражение в _Alignof или _Generic оператор не оценивается. Выражение в sizeof оператор оценивается только, если он необходим для вычисления размера массива переменной длины, например sizeof(a[n++]).

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

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

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

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

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

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

Пример - Шаг в 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);
}

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

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

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

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