Описание
Возможная недопустимая операция на булевом операнде происходит, когда вы используете булев операнд в арифметике, реляционной, или битовой операции и:
Булев операнд имеет представление прерывания. Размер булева типа в памяти является по крайней мере одним адресуемым модулем (размер char
). Булев тип требует, чтобы только один бит представлял значение true (1)
или false (0)
. Представление булева операнда в памяти содержит дополнительные биты. Представление памяти может привести к значениям, которые не являются true
или false
, представление прерывания.
Результат операции может превысить точность булева операнда.
Например, в этом фрагменте кода:
Если значение 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);
}