AUTOSAR C++14 Rule A4-7-1

Целое выражение не должно приводить к потере данных

Описание

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

Целое выражение не должно приводить к потере данных.

Объяснение

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

  • Неявное преобразование из uint16_t к uint8_t отбрасывает высокий байт большего типа данных.

  • Арифметическое выражение с целыми числами со знаком, которое приводит к переполнению, является неопределенным поведением.

Чтобы убедиться, что никакая неожиданная потеря данных не происходит:

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

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

Реализация Polyspace

  • Polyspace® флаги эти интегральные выражения, которые могут привести к потере данных:

    • Операция на со знаком или беззнаковом целом переменные, который приводит к переполнению.

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

    • Преобразование целого числа (без знака) со знаком к более узкому целочисленному типу (без знака) со знаком.

    • Преобразование беззнакового целого к целому числу со знаком.

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

  • Polyspace не отмечает использование static_cast бросать к более узкому типу. Программное обеспечение принимает, что они, преобразование является намеренным, даже если они могут привести к потере данных.

Поиск и устранение проблем

Если вы ожидаете нарушение правила, но не видите его, относитесь, чтобы Диагностировать, Почему Кодирующие Стандартные Нарушения Не Появляются как ожидалось.

Примеры

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

#include <iostream>
#include <cstdint>
#include <stdexcept>
#include <climits>

uint8_t sum(uint8_t a, uint8_t b) noexcept
{
    return (a + b); //Non-compliant
}

uint8_t sum_check(uint8_t a, uint8_t b)
{
    if (b > UCHAR_MAX - a) {
        throw std::range_error("Operation overflows");
    }
    return (a + b); // Compliant
}

int16_t increment(int16_t var)
{
    return ++var; //Non-compliant
}


void func()
{

    uint8_t small_sum = sum(50, 50);
    uint8_t large_sum = sum(150, 150); 
    try {
        uint8_t large_sum_check = sum_check(150, 150);
    } catch (std::range_error&) {
        //Handle error
    }

    int16_t max_var = increment(SHRT_MAX);

}

В этом примере, флагах Polyspace:

  • Оператор возврата sum() потому что второй вызов sum() инициализировать large_sum результаты в переполнении. Сумма входных параметров превышает размер типа возврата (uint8_t).

  • Целое выражение increment() потому что вызов при инициализации max_var попытки постепенно увеличить SHRT_MAX.

Polyspace не отмечает оператор возврата sum_check потому что функция проверяет область значений своих входных параметров и выдает ошибку когда large_sum_check инициализируется.

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

Группа: Стандартные преобразования
Категория: необходимый, автоматизированный

Советы

Polyspace Bug Finder™ делает определенные предположения о значениях входных параметров. Смотрите Аналитические Предположения Bug Finder.

За счет возможно более длинного времени выполнения можно выполнить более исчерпывающий анализ, где все значения входных параметров функции рассматриваются при показе дефектов, включая входные параметры невостребованных функций. Смотрите Run stricter checks considering all values of system inputs (-checks-using-system-input-values).

Введенный в R2021b