У меня возник интересный сценарий, в котором у меня разные результаты в зависимости от типа правильного операнда, и я не могу понять причину этого.
Вот минимальный код:
#include <iostream>
#include <cstdint>
int main()
{
uint16_t check = 0x8123U;
uint64_t new_check = (check & 0xFFFF) << 16;
std::cout << std::hex << new_check << std::endl;
new_check = (check & 0xFFFFU) << 16;
std::cout << std::hex << new_check << std::endl;
return 0;
}
Я скомпилировал этот код с g++ (gcc версии 4.5.2) на Linux 64bit: g++ -std = С++ 0x -Wall example.cpp -o example
Выход был:
ffffffff81230000
81230000
Я не могу понять причину вывода в первом случае.
Почему в какой-то момент любой из результатов временного расчета будет продвигаться до знака подписанного 64-битного (int64_t
), что приведет к расширению знака?
Я бы принял результат "0" в обоих случаях, если 16-битное значение сдвинуто на 16 бит, оставив в первую очередь, а затем продвинуто до 64-битного значения. Я также принимаю второй вывод, если компилятор сначала продвигает check
в uint64_t
, а затем выполняет другие операции.
Но как получилось, что &
с 0xFFFF (int32_t
) против 0xFFFFU (uint32_t
) приведет к этим двум разным выходам?