主要内容

移位运算无效

移位运算无效

描述

对变量 var 的移位运算进行的此检查确定以下事项:

  • 移位量是否大于 var 的类型允许的范围。

  • 如果移位是左移位,则确定 var 是否为负数。

示例

全部展开

#include <stdlib.h>
#define shiftAmount 32
enum shiftType {
 SIGNED_LEFT,
 SIGNED_RIGHT,
 UNSIGNED_LEFT,
 UNSIGNED_RIGHT
};

enum shiftType getShiftType();

void main() {
  enum shiftType myShiftType = getShiftType();
  int signedInteger = 1;
  unsigned int unsignedInteger = 1;
  switch(myShiftType) {
  case SIGNED_LEFT: 
    signedInteger = signedInteger << shiftAmount;
    break;
  case SIGNED_RIGHT: 
    signedInteger = signedInteger >> shiftAmount;
    break;
  case UNSIGNED_LEFT: 
    unsignedInteger = unsignedInteger << shiftAmount;
    break;
  case UNSIGNED_RIGHT: 
    unsignedInteger = unsignedInteger >> shiftAmount;
    break;
  }
}

在上方示例中,对于有符号的和无符号的 int,移位量 shiftAmount 都处于允许的范围之外。因此,移位运算无效检查会生成红色错误。

更正 — 使移位量保持在边界内

一种可能的更正方法是:对于无符号整数,使移位量保持在范围 0..31 内;对于有符号整数,使移位量保持在范围 0...30 内。如果 int 的大小在目标处理器上为 32,则此更正方法可行。

#include <stdlib.h>
#define shiftAmountSigned 30
#define shiftAmount 31
enum shiftType {
 SIGNED_LEFT,
 SIGNED_RIGHT,
 UNSIGNED_LEFT,
 UNSIGNED_RIGHT
};

enum shiftType getShiftType();

void main() {
  enum shiftType myShiftType = getShiftType();
  int signedInteger = 1;
  unsigned int unsignedInteger = 1;
  switch(myShiftType) {
  case SIGNED_LEFT: 
    signedInteger = signedInteger << shiftAmountSigned;
  
    break;
  case SIGNED_RIGHT: 
    signedInteger = signedInteger >> shiftAmountSigned;
  
    break;
  case UNSIGNED_LEFT: 
    unsignedInteger = unsignedInteger << shiftAmount;
  
     break;
  case UNSIGNED_RIGHT: 
    unsignedInteger = unsignedInteger >> shiftAmount;
  
    break;
  }
}
void main(void) {
  int x = -200;
  int y;
  y = x << 1; 
}

在上方示例中,左移位运算的左操作数为负数。

更正 — 使用 Polyspace 分析选项

您可以对负数使用左移位并且不生成红色的移位运算无效错误。要允许这样的左移位,请在配置窗格中的检查行为下选择允许左移负操作数

void main(void) {
  int x = -200;
  int y;
  y = x << 1; 
}
short getVal();

int foo(void) {
  long lvar;
  short svar1, svar2;

  lvar = 0;
  svar1 = getVal();
  svar2 = getVal();

  lvar =  (svar1 - svar2) << 10;
  if (svar1 < svar2)  {
    return 1;
  } else {
    return 0;
  }
}

int main(void) {
  return foo();
}

在上方示例中,如果 svar1 < svar2,则 << 的左操作数可能为负数。因此,对 << 进行的移位运算检查显示为橙色。在橙色检查之后,包含该错误的执行路径会被截断。因此,在橙色的移位运算无效检查之后,Polyspace® 会假设 svar1 >= svar2。该语句的分支 if(svar1 < svar2) 不可达。

检查信息

组:数值
语言:C | C++
缩写:SHF