Main Content

AUTOSAR C++14 Rule A4-7-1

An integer expression shall not lead to data loss

Since R2021b

Description

Rule Definition

An integer expression shall not lead to data loss.

Rationale

A data loss might occur if you perform an explicit cast or if your integer expression results in an implicit conversion, an overflow, an underflow, or a wraparound. For instance:

  • An implicit conversion from uint16_t to uint8_t discards the high byte of the larger data type.

  • An arithmetic expression with signed integers that results in an overflow is undefined behavior.

To make sure that no unexpected data loss occurs:

  • Avoid integral type conversions by performing all operations in a uniform type.

  • Use appropriate guards (such as asserts and if statements) to handle other possible causes of data loss.

Polyspace Implementation

  • Polyspace® flags these integral expressions that might result in data loss:

    • Operation on a signed or an unsigned integer variables that results in an overflow.

    • Assignment of a compile-time constant to signed or unsigned integer variables whose data type cannot accommodate the value of that constant.

    • Conversion of a signed (unsigned) integer to a narrower signed (unsigned) integer type.

    • Conversion of an unsigned integer to a signed integer.

    • Shift operation that results in a value that cannot be represented by the result data type.

  • Polyspace does not flag the use of static_cast to cast to a narrower type. The software assumes that these conversion are intentional even if they might result in data loss.

Extend Checker

A default Bug Finder analysis might not raise a violation of this rule when the input values are unknown and only a subset of inputs can cause an issue. To check for violations caused by specific system input values, run a stricter Bug Finder analysis. See Extend Bug Finder Checkers to Find Defects from Specific System Input Values.

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#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);

}

In this example, Polyspace flags:

  • The return statement of sum() because the second call to sum() to initialize large_sum results in an overflow. The sum of the input parameters exceeds the size of the return type (uint8_t).

  • The integer expression of increment() because the call when initializing max_var attempts to increment SHRT_MAX.

Polyspace does not flag the return statement of sum_check because the function checks the range of its inputs and throws an error when large_sum_check is initialized.

Check Information

Group: Standard conversions
Category: Required, Automated

Tips

Polyspace Bug Finder™ makes certain assumptions about the values of inputs. See Bug Finder Analysis Assumptions.

At the cost of a possibly longer runtime, you can perform a more exhaustive analysis where all values of function inputs are considered when showing defects, including inputs of uncalled functions. See Run stricter checks considering all values of system inputs (-checks-using-system-input-values).

Version History

Introduced in R2021b