﻿# V1046\. Unsafe usage of the 'bool' and integer types together in the operation '&\='\.

Анализатор обнаружил небезопасное использование типа 'bool' и целочисленного типа вместе в операции побитового И\. Проблема в том, что побитовое И вернет 'false' для четных чисел, так как младший разряд всегда равен нулю\. Если же привести вручную численный тип к 'bool', то всё будет в порядке\.

Рассмотрим синтетический пример:

```cpp
int foo(bool a)
{
  return a ? 0 : 2;
}
....
bool var = ....;
var &= foo(false);
```

Независимо от начального значения переменной 'var', после выполнения операции '&\=' эта переменная будет иметь значение 'false'\. Допустим, функция 'foo' вернёт значение 2\. Тогда операция 'var & 2' всегда даёт в результате 0, так как возможные значения 'var' это только 0 или 1\.

Этот код следует исправить так:

```cpp
var &= foo(false) != 0;
```

или же можно изменить и возвращаемое функцией значение:

```cpp
int foo(bool a)
{
  return a ? 0 : 1;
}
```

Если, например, функция будет возвращать только значения из диапазона \[0;1\], то всё в порядке, так как мы можем привести их без потерь к bool\.

Пример ошибки, найденной с помощью этой диагностики в реальном проекте:

```cpp
template<class FuncIterator>
bool SetFunctionList( FuncIterator begin, FuncIterator end) {
  bool ret = true;
  for (FuncIterator itr = begin; itr != end; ++itr) {
    const ROOT::Math::IMultiGenFunction *f = *itr;
    ret &= AddFunction(*f);
  }
  return ret;
}

int AddFunction(const ROOT::Math::IMultiGenFunction & func) {
  ROOT::Math::IMultiGenFunction *f = func.Clone();
  if (!f) return 0;
  fFunctions.push_back(f);
  return fFunctions.size();
}
```

Предполагалось, что функция 'SetFunctionList' проверяет валидность переданных ей итераторов и возвращает 'false', если хоть один из них невалидный, иначе 'true'\. Но программист допустил ошибку при работе с оператором '&\='\. Правый аргумент – функция, которая возвращает целое число в диапазоне от 0 до SIZE\_MAX\. При возвращении чётных чисел из функции 'AddFunction', переменная 'ret' будет обнуляться, хотя должна это делать только для невалидных итераторов\.

Исправленная функция 'SetFunctionList', где результат функции 'AddFunction' предварительно приводится к типу 'bool':

```cpp
template<class FuncIterator>
bool SetFunctionList( FuncIterator begin, FuncIterator end) {
  bool ret = true;
  for (FuncIterator itr = begin; itr != end; ++itr) {
    const ROOT::Math::IMultiGenFunction *f = *itr;
    ret &= (bool)AddFunction(*f);
  }
  return ret;
}
```