Почему компилятор C не выдает предупреждение при использовании сдвига битов на отрицательное значение? - PullRequest
0 голосов
/ 18 июня 2020

Почему я не получаю предупреждения типа

смещение отрицательного числа не допускается

, когда я использую следующий код:

#include <stdio.h>

int main (){

    int k = -5;
    unsigned int shift = 2;
    unsigned ans = (k >> shift);

    printf("ans:%u\n",ans);

    return 0;
}

Ответы [ 3 ]

3 голосов
/ 18 июня 2020

В C вам разрешено сдвигать отрицательные числа. Результат операции варьируется от системы к системе в зависимости от того, интерпретирует ли компилятор сдвиг как арифметический c сдвиг или логический сдвиг . Логический сдвиг заполняет верхние биты результата нулями, а арифметический c сдвиг заполняет верхние биты результата единицами, если исходное число было отрицательным.

Результат называется , определяемый реализацией, что означает, что каждый компилятор должен задокументировать, какое специфическое c поведение он собирается использовать. Так что проверьте документацию вашего компилятора для получения более подробной информации.

Тот факт, что это определяется реализацией, может объяснить, почему здесь нет предупреждений. Сдвиг отрицательного числа - это совершенно законный код C; просто это не всегда означает одно и то же во всех системах.

Надеюсь, это поможет!

0 голосов
/ 18 июня 2020

сдвиг числа со знаком вправо определяется реализацией. В большинстве современных реализаций будет использоваться арифметический c сдвиг (и 2 дополнительных числа)

Арифметический c сдвиг: enter image description here

0 голосов
/ 18 июня 2020

смещение отрицательного числа не допускается

Это неверно. Сдвиг вправо для отрицательного числа разрешен , хотя результат определяется реализацией.

...