Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Division is between two operands of arithmetic type. Overflow can occur during two's complement signed integer division when the dividend is equal to the minimum (negative) value for the signed integer type and the divisor is equal to −1. Division operations are also susceptible to divide-by-zero errors. (See INT33-C. Ensure that division and modulo remainder operations do not result in divide-by-zero errors.) AnchorModuloModulo

Modulo

...

Noncompliant Code Example

This noncompliant code example can result in a divide-by-zero error during the division of the signed operands s_a and s_b. It can also result in a signed integer overflow error on twos-complement platforms. The x86-32 architecture, for example, requires that both conditions result in a fault, which can easily result in a denial-of-service attack.

Code Block
bgColor#FFcccc
langc
void func(signed long s_a, signed long s_b) {
  if ((s_b == 0) {
    /* Handle error */
  } else {
    signed long result = s_a / s_b;
  }
  /* ... */
}

Compliant Solution

This compliant solution tests the suspect division operation to guarantee there is no possibility of divide-by-zero errors or signed overflow:

Code Block
bgColor#ccccff
langc
#include <limits.h>
 
void func(signed long s_a, signed long s_b) {
  signed long result;
  if ((s_b == 0) || ((s_a == LONG_MIN) && (s_b == -1))) {
    /* Handle error */
  } else {
    result = s_a / s_b;
  }
  /* ... */
}


Anchor
Modulo
Modulo

Remainder

The remainder operator provides the remainder when two operands of integer type are divided. Because many platforms implement remainder and division in the same instruction, the remainder operator has the same possibilities of arithmetic overflow and division by 0. (See INT33-C. Ensure that division and remainder operations do not result in divide-by-zero errors.)

Noncompliant Code Example

Many hardware platforms implement remainder as part of the division operator, which can overflow. Overflow can occur during a remainder operation when the dividend is equal to the minimum (negative) value for the signed integer type and the divisor is equal to −1. This occurs even though the result of such a remainder operation is mathematically 0.

Code Block
bgColor#FFcccc
langc
#include <limits.h>

void func(signed long s_a, signed long s_b) {
  if (s_b == 0) {
    /* Handle error */
  } else {
    signed long result = s_a % s_b;
  }
  /* ... */
}

Implementation Details

On x86 platforms, the remainder operator for signed integers is implemented by the idiv instruction code, along with the divide operator. Because LONG_MIN / -1 overflows, this code will throw a floating-point exception on LONG_MIN % -1.

On Microsoft Visual Studio 2013, taking the remainder of LONG_MIN by −1 results in abnormal termination on x86 and x64. On GCC/Linux, taking the remainder of LONG_MIN by −1 produces a floating-point exception. However, on GCC 4.2.4 and newer, with optimization enabled, taking the remainder of LONG_MIN by −1 yields the value 0.

Compliant Solution

This compliant solution tests the remainder operand to guarantee there is no possibility of an overflow or divide-by-zero error:

Code Block
bgColor#ccccff
langc
#include <limits.h>
 
void func(signed long s_a, signed long s_b) {
  signed long result;
  if ((s_b == 0 ) || ((s_a == LONG_MIN) && (s_b == -1))) {
    /* Handle error */
  } else {
    result = s_a % s_b;
  }
  
  /* ... */
}

Anchor
Left Shift Operator
Left Shift Operator

...

The unary negation operator takes an operand of arithmetic type. Overflow can occur during two's complement unary negation when the operand is equal to the minimum (negative) value for the signed integer type.

Noncompliant Code Example

This noncompliant code example can result in a signed integer overflow during the unary negation of the signed operand s_a:

Code Block
bgColor#FFcccc
langc
void func(signed long s_a) {
  signed long result = -s_a;

  /* ... */
}

Compliant Solution

This compliant solution tests the suspect negation operation to guarantee there is no possibility of signed overflow:

...

This section includes an example for the addition of atomic integer types only. For other operations, tests similar to the precondition tests for two’s complement integers used for nonatomic integer types can be used.

Noncompliant Code Example

This noncompliant code example using atomic integers can result in unexpected signed integer overflow:

Code Block
bgColor#FFcccc
langc
#include <stdatomic.h>
 
atomic_int i;

void func(int si_a) {
  atomic_init(&i, 42); 
  atomic_fetch_add(&i, si_a);

  /* ... */
}

Compliant Solution

This compliant solution tests the operands to guarantee there is no possibility of signed overflow. It loads the value stored in the atomic integer and tests for possible overflow before performing the addition. However, this code contains a race condition where i can be modified after the load, but prior to the atomic store. This solution is only compliant if i is guaranteed to only be access by a single thread. See CON43-C. Do not assume that a group of calls to independently atomic methods is atomic for more information.

...

...