exponenta event banner

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

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

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