CERT C: Rule FLP34-C

Убедитесь, что преобразования с плавающей точкой в области значений нового типа

Описание

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

Убедитесь, что преобразования с плавающей точкой в области значений нового типа.[1]

Реализация Polyspace

Это средство проверки проверяет на:

  • Переполнение преобразования плавающее

  • Плавающая точка к целочисленному переполнению преобразования

Примеры

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

Проблема

Переполнение преобразования плавающее происходит при преобразовании значения с плавающей точкой в меньший тип данных с плавающей запятой. Если переменная не имеет достаточной памяти, чтобы представлять исходное значение, переполнение преобразования.

Точное выделение ресурсов хранения для различных типов с плавающей точкой зависит от вашего процессора. Смотрите Target processor type (-target).

Риск

Переполнение может привести к непредсказуемым значениям от расчетов. Результатом может быть бесконечность или максимальное конечное значение в зависимости от округляющегося режима, используемого в реализации. Если вы используете результат переполняющегося преобразования в последующих расчетах и не объясняете переполнение, вы видите неожиданные результаты.

Исправление

Фиксация зависит от первопричины дефекта. Часто детали результата показывают последовательность событий, которые привели к дефекту. Используйте этот список событий, чтобы определить, как преобразовываемая переменная получает свое текущее значение, можно реализовать закрепление на любом событии в последовательности. Если детали результата не показывают историю события, можно проследить использование, щелкните правой кнопкой по опциям по исходному коду и смотрите предыдущие связанные события. См. также Интерпретируют Результаты Bug Finder в Пользовательском интерфейсе Рабочего стола Polyspace.

Можно зафиксировать дефект:

  • Используя больший тип данных для результата преобразования так, чтобы все значения могли быть вмещены.

  • Проверка значения, которые приводят к переполнению и выполнению соответствующей обработки ошибок.

В общем случае избегайте преобразований в меньшие типы с плавающей точкой.

Смотрите примеры мер ниже.

Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. См.:

Пример - преобразующий от double к float
float convert(void) {

    double diam = 1e100;
    return (float)diam;
}

В операторе возврата, переменной diam типа double (64 бита) преобразован в переменную плавания типа (32 бита). Однако значение 1^100 требует, чтобы больше чем 32 бита были точно представлены.

Проблема

Плавающая точка к целочисленному переполнению преобразования происходит при преобразовании значения с плавающей точкой в целочисленный тип данных. Если целая часть значения не может быть представлена в устройстве хранения данных, доступном для целочисленного типа данных, переполнения преобразования.

Риск

При преобразовании от плавающей точки до целочисленных типов, если значение с плавающей точкой находится вне области значений, которая может быть представлена целочисленным типом, поведение не определено (C Стандартные 6.3.14 и 6.3.15).

Исправление

Можно зафиксировать дефект:

  • Используя больший тип данных для результата преобразования так, чтобы все значения могли быть вмещены.

  • Проверка значения, которые приводят к переполнению и выполнению соответствующей обработки ошибок.

    Проверка на переполнение значений на float переменная var может быть похожим на это:

    if  isnan(var) 
        || popcount(INT_MAX) < log2f(fabsf(var)) 
        || (var != 0.0F && fabsf(var) < FLT_MIN)){
        // Handle error
    }
    else {
        // Perform operations on var
    }
    
    Проверка определяет, является ли значение с плавающей точкой представимым в целочисленном типе:

    • Значением не является NaN.

    • Количество битов, требуемых сохранить значение, меньше количества битов в INT_MAX (самое большое целое число, что int тип может представлять). popcount функция (не заданный здесь) считает количество 1's (или биты набора) в номере.

    • Значение с плавающей точкой не ниже, чем наименьшее представимое значение с плавающей точкой.

Пример – значение с плавающей точкой, конвертированное до целого числа, не обрабатывая переполнение
void func(float fVar) {
  int iVar;  
  iVar = fVar; //Noncompliant
}

В этом примере, значении с плавающей точкой fVar не проверяется на переполнение прежде, чем преобразовать в целочисленный тип. Начиная с аргумента fVar может содержать значения, которые не являются представимыми в int тип данных, анализ отмечает потенциальное переполнение.

Обратите внимание на то, что func не называется в этом примере, и переполнение является только возможностью. Чтобы видеть проблемы этих типов, добавьте опцию анализа Run stricter checks considering all values of system inputs (-checks-using-system-input-values).

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

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

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