CERT C: Rule EXP46-C

Не используйте побитовый оператор с подобным булевской переменной операндом

Описание

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

Не используйте побитовый оператор с подобным булевской переменной операндом. [1]

Примеры

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

Описание

Возможная недопустимая операция на булевом операнде происходит, когда вы используете булев операнд в арифметике, реляционной, или битовой операции и:

  • Булев операнд имеет представление прерывания. Размер булева типа в памяти является по крайней мере одним адресуемым модулем (размер char). Булев тип требует, чтобы только один бит представлял значение true (1) или false (0). Представление булева операнда в памяти содержит дополнительные биты. Представление памяти может привести к значениям, которые не являются true или false, представление прерывания.

  • Результат операции может превысить точность булева операнда.

Например, в этом фрагменте кода:

bool_v >> 2

  • Если значение bool_v true (1) или false (0), поразрядный сдвиг превышает однобитную точность bool_v и всегда результаты в 0.

  • Если bool_v имеет представление прерывания, результатом операции является произвольное значение.

Возможная недопустимая операция на булевом операнде не повышает дефекта когда:

  • Операция не приводит к переполнению точности. Например, поразрядный & или | операции с 0x01 или 0x00.

  • Булев операнд не может иметь представления прерывания. Например, константное выражение, которое приводит к 0 или 1, или сравнение, оцененное к true или false.

Риск

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

Фиксация

Постарайтесь не выполнять операции на булевых операндах кроме этих операций:

  • Операция Assignment (=).

  • Операции равенства (== или !=).

  • Логические операции, ||, или !).

Пример - возможное представление прерывания булева операнда

#include <stdio.h>
#include <stdbool.h>

#define BOOL _Bool

int arr[2] = {1, 2};

int func(BOOL b)
{
    return arr[b];
}

int main(void)
{
    BOOL b;
    char* ptr = (char*)&b;
    *ptr = 64;
    return func(b);
}

В этом примере, булев операнд b используется в качестве индекса массива в func для массива с двумя элементами. В зависимости от компилятора и оптимизации отмечает вас использование, значение b не может быть 0 или 1. Например, в Linux® Debian 8, если вы используете gcc версия 4.9 с флагом -O0 оптимизации, значение b 64, который вызывает переполнение буфера.

Коррекция — использует только последнее значение значимого бита булева операнда

Одна возможная коррекция должна использовать переменную b0 из типа unsigned int получить только значение последнего значимого бита булева операнда. Значение этого бита находится в области значений [0..1], даже если булев операнд имеет представление прерывания.

#include <stdio.h>
#include <stdbool.h>

#define BOOL _Bool

int arr[2] = {1, 2};

int func(BOOL b)
{
    unsigned int b0 = (unsigned int)b;
    b0 &= 0x1;
    return arr[b0];
}

int main(void)
{
    BOOL b;
    char* ptr = (char*)&b;
    *ptr = 64;
    return func(b);
} 

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

Группа: правило 03. Выражения (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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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