Смещение сдвига отрицательное или слишком большая ошибка - правильное решение?
У меня есть следующая функция для чтения четырехъядерного квадратика (в абстрактном классе ввода/вывода базового файла):
unsigned long long File::readBigEndQuadWord(){
unsigned long long qT = 0;
qT |= readb() << 56;
qT |= readb() << 48;
qT |= readb() << 40;
qT |= readb() << 32;
qT |= readb() << 24;
qT |= readb() << 16;
qT |= readb() << 8;
qT |= readb() << 0;
return qT;
}
Функции readb() читают BYTE. Вот используемые typedefs:
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
Дело в том, что я получаю 4 предупреждения компилятора на первых четырех строках со сдвигом:
предупреждение C4293: '< <: количество сдвигов отрицательный или слишком большой, undefinedПоведение
Я понимаю, почему это предупреждение происходит, но я не могу понять, как избавиться от него правильно. Я мог бы сделать что-то вроде:
qT |= (unsigned long long)readb() << 56
;
Это приведет к удалению предупреждения, но не существует другой проблемы, будет ли BYTE правильно распространяться все время? Может быть, я просто думаю об этом слишком много, и решение так просто. Можете ли вы, ребята, помочь мне здесь? Спасибо.
Ответы
Ответ 1
Ваш способ удаления предупреждения правильный. Как вы, наверное, уже знаете, предупреждение возникает, потому что вы пытаетесь переместить содержимое байта за пределы слова, а затем сохраните его в квадратике. Эта операция undefined. (Он будет оценивать правую часть задания перед назначением значения.) Явным образом бросая сначала, теперь есть достаточно места, чтобы сделать сдвиг, поэтому нечего жаловаться.
Возможно, компилятор должен понять, что вы собираетесь хранить его в квадратике, поэтому сначала нужно выделить квадловое слово и сделать сдвиг там, но он, возможно, не был настолько умен, чтобы понять это.
Кроме того, я не уверен в этом, но, возможно, компиляция этого для x64 также не сгенерирует предупреждение, так как одно слово - 64 бита?
Ответ 2
qT | = (unsigned long long) readb() < (shiftvalue и 63);
Это будет идеальным решением, предполагая, что вы не захотите более 63 бит сдвига