正しいオペランドの型に応じて異なる結果が得られるという興味深いシナリオに直面しましたが、その理由がよくわかりません。
最小限のコードは次のとおりです。
#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;
}
Linux 64 ビットで g++ (gcc バージョン 4.5.2) を使用してこのコードをコンパイルしました: g++ -std=c++0x -Wall example.cpp -o example
出力は次のとおりです。
ffffffff81230000
81230000
最初のケースでの出力の理由がよくわかりません。
ある時点で、一時的な計算結果のいずれかが符号付き 64 ビット値 ( )に昇格さint64_t
れ、符号が拡張されるのはなぜですか?
最初に 16 ビット値が 16 ビット左にシフトされ、次に 64 ビット値に昇格された場合、どちらの場合も「0」の結果を受け入れます。check
コンパイラが最初にtoをプロモートしてからuint64_t
他の操作を実行する場合、2 番目の出力も受け入れます。
しかし、どうして&
0xFFFF ( int32_t
) と 0xFFFFU ( uint32_t
) を比較すると、これら 2 つの異なる出力になるのでしょうか?