Main Content

Integer constant overflow

Constant value falls outside range of integer data type

Description

This defect occurs in the following cases:

  • You assign a compile-time integer constant to a signed integer variable whose data type cannot accommodate the value.

    See Constant Overflows from Assignments.

  • You use an enum value that cannot be accommodated by the underlying type of the enum (and the underlying type is signed). For most C compilers, the default underlying type is signed int (based on the C standard).

    See Constant Overflows from enum Values.

  • You perform a binary operation involving two integer constants that results in an overflow, that is, a value outside the range allowed by the data type that the operation uses. A binary operation with integer constants uses the signed int data type (unless you use modifiers such as u or L).

    See Constant Overflows from Binary Operations.

An n-bit signed integer holds values in the range [-2n-1, 2n-1-1]. For instance, c is an 8-bit signed char variable that cannot hold the value 255.

signed char c = 255;

This defect checker depends on the following options:

You do not see the defect in these situations:

  • Creation of new constants from const variables (for specific compilers only).

    Different compilers might define compile-time constants differently. In the following code, c+1 is considered a compile-time constant by GCC compilers, but not by the standard C compiler:

    const int16_t c = 32767;
    int16_t y = c + 1;
    Whether you see a violation of this check on y might depend on your compiler.

  • Bitwise NOT operation.

    Polyspace® does not raise this violation when you perform a bitwise NOT operation.

Risk

The default behavior for constant overflows can vary between compilers and platforms. Retaining constant overflows can reduce the portability of your code.

Even if your compilers wraps around overflowing constants with a warning, the wrap-around behavior can be unintended and cause unexpected results.

Fix

Check if the constant value is what you intended. If the value is correct, use a different, possibly wider, data type for the variable.

Examples

expand all

#define MAX_UNSIGNED_CHAR 255 
#define MAX_SIGNED_CHAR 127

void main() {
    char c1 = MAX_UNSIGNED_CHAR;
    char c2 = MAX_SIGNED_CHAR+1;
}

In this example, the defect appears on the macros because at least one use of the macro causes an overflow. To reproduce these defects, use a Target processor type (-target) where char is signed by default.

Correction — Use Different Data Type

One possible correction is to use a different data type for the variables that overflow.

#define MAX_UNSIGNED_CHAR 255 
#define MAX_SIGNED_CHAR 127

void main() {
    unsigned char c1 = MAX_UNSIGNED_CHAR;
    unsigned char c2 = MAX_SIGNED_CHAR+1;
}
enum {
  a=0x7fffffff,
  b,
  c=0xffffffff
} MyEnumA;

In this example, the enum has an underlying type int. The int type can accommodate values in the range [-231, 231-1]. However, the value of the enumerator b is 0x80000000 or 231 (one more than the previous value a). This value falls outside the allowed range of int.

The value of c, that is 0xffffffff or 232-1, is even larger and also causes an overflow.

To see this defect:

const unsigned int K_ATM_Label_Ram_init_value [] = {
     0x06 | ( 3 << 29) ,
     0x80 | ( 9 << 29) ,
     ( 2 << 31 )         ,
};

In this example, two of the shift operations result in values that cannot be accommodated by the signed int data type. The signed int data type can accommodate values in the range [-231, 231-1]. The operation:

  • 9 << 29 results in the value 232+536870912.

  • 2 << 31 results in the value 232.

Note that even though the result is assigned to an unsigned int variable, the overflow detection uses the underlying type of the binary operation, that is, signed int.

Result Information

Group: Numerical
Language: C | C++
Default: Off
Command-Line Syntax: INT_CONSTANT_OVFL
Impact: Medium

Version History

Introduced in R2018b