Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: fixed first NCE/CS pair

...

This noncompliant code example fails to ensure that left and right operands have nonnegative values and that the right operand is less than or equal to the precision of the promoted left operand. The example can also produce This example does check for signed integer overflow ; see in compliance with INT32-C. Ensure that operations on signed integers do not result in overflow for more information.

Code Block
bgColor#FFcccc
langc
#include <limits.h>
#include <stddef.h>
#include <inttypes.h>
 
extern size_t popcount(uintmax_t);
#define PRECISION(x) popcount(x)

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

Shift operators and other bitwise operators should be used only with unsigned integer operands in accordance with INT13-C. Use bitwise operators only on unsigned operands.

Compliant Solution (Left Shift, Signed Type)

This compliant solution eliminates the possibility of overflow resulting from a left-shift operationIn addition to the check for overflow, this compliant solution ensures that both the left and right operands have nonnegative values and that the right operand is less than or equal to the precision of the promoted left operand:

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

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

...