В большинстве выражений целочисленные типы ранга, меньшие, чем int
, преобразуются в int
(если int
может представлять все значения без потерь) или unsigned int
(в противном случае).
Чтобы упростить его, рассмотрим ранг, который соответствует количеству битов в типе, чем больше битов, тем выше ранг (для окончательной обработки термина см. Справочник по языку (например, здесь вы можете начать ))).
И здесь, похоже, дело в том, что тип, возвращаемый UINT8_C()
(возможно, unsigned char
в скрытой форме), имеет меньший ранг, чем int
, и в результате вы получитеТип со знаком.
Теперь, причина предупреждения состоит в том, что смещение целочисленных типов со знаком недостаточно хорошо определено во всех случаях.Сдвиг отрицательных значений влево или переполнение при сдвиге составляет неопределенное поведение , что означает, что программа может вести себя неправильно различными способами, если встречается любое из этих двух условий.(При смещении типов без знака допустимо переполнение, вы получаете усеченное значение).
Кроме того, число смещений не может быть отрицательным.
Однако, если это точный код,предупреждение не нужно, потому что должно быть очевидно, что смещение 0 влево на 4 позиции абсолютно безопасно.Если вы используете переменные вместо констант, компилятор (или инструмент) не всегда сможет вывести безопасность этого сдвига, и в этом случае вам следует обратить внимание на предупреждение и переписать свой код таким образом, чтобы не было нинеопределенное поведение или предупреждение.