Для получения триального ключа
заполните форму ниже
Team License (базовая версия)
Enterprise License (расширенная версия)
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
GBP
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Бесплатная лицензия PVS-Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

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

Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
>
V1046. Unsafe usage of the 'bool' and i…
Сообщения PVS-Studio
Диагностики общего назначения (General Analysis, C++)
Диагностики общего назначения (General Analysis, C#)
Диагностики общего назначения (General Analysis, Java)
Диагностика микро-оптимизаций (C++)
Диагностика 64-битных ошибок (Viva64, C++)
Cтандарт MISRA
Стандарт AUTOSAR
Стандарт OWASP (C#)
Дополнительная информация
Оглавление

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

10 Окт 2019

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

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

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

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

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

var &= foo(false) != 0;

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

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

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

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

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':

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;
}

Данная диагностика классифицируется как:

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V1046.

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