Invalid shift operations

Операции сдвига недопустимы

Описание

Это проверяет операции сдвига на переменной 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;
  }
}

В этом примере, сумма сдвига shiftAmount находится вне позволенной области значений и для подписанного и для int без знака. Поэтому проверка Invalid shift operations производит красную ошибку.

Коррекция — Сохраняет сумму сдвига внутри границ

Одна возможная коррекция должна сохранить сумму сдвига в области значений 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 Использования

Можно использовать сдвиги влево на отрицательных числах и не произвести красную ошибку Invalid shift operations. Чтобы позволить такие сдвиги влево, на панели Configuration, под Check Behavior, выбирают Allow negative operand for left shifts.

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, левый операнд << может быть отрицательным. Поэтому Shift operations проверяет << является оранжевым. После оранжевой проверки пути к выполнению, содержащие ошибку, становятся усеченными. Поэтому после оранжевой проверки Invalid shift operations, Polyspace® принимает тот svar1 >= svar2. Ветвь оператора, if(svar1 < svar2), недостижимо.

Проверяйте информацию

Группа: числовой
Язык: C | C++
Акроним: SHF