Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: xferred left shift operator code examples from INT32-C to INT34-C

...

The left-shift operator is between two operands of integer type.

Noncompliant Code Example

This noncompliant code example can result in signed integer overflow:

Code Block
bgColor#FFcccc
langc
void func(signed long si_a, signed long si_b) {
  signed long result = si_a << si_b;

  /* ... */
}

Compliant Solution

This compliant solution eliminates the possibility of overflow resulting from a left-shift operation:

Code Block
bgColor#ccccff
langc
#include <limits.h>
#include <stddef.h>
#include <inttypes.h>
 
extern size_t popcount(uintmax_t);
#define UWIDTH(umax_value) popcount(umax_value) 

void func(signed long si_a, signed long si_b) {
  signed long result;
  if ((si_a < 0) || (si_b < 0) ||
      (si_b >= UWIDTH(ULONG_MAX)) ||
      (si_a > (LONG_MAX >> si_b))) {
    /* Handle error */
  } else {
    result = si_a << si_b;
  }
 
  /* ... */
}

AnchorLeft Shift OperatorLeft Shift OperatorThe UWIDTH() macro provides the correct width for an unsigned integer type (see INT19-C. Correctly compute integer widths). This solution also complies with For examples of usage of the left-shift operator, see INT34-C. Do not shift a negative number of bits or more bits than exist in the operand.

Atomic Integers

The C Standard defines the behavior of arithmetic on atomic signed integer types to use two's complement representation with silent wraparound on overflow; there are no undefined results. However, although defined, these results may be unexpected and therefore carry similar risks to unsigned integer wrapping (see INT30-C. Ensure that unsigned integer operations do not wrap). Consequently, signed integer overflow of atomic integer types should also be prevented or detected. 

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.

...