簡體   English   中英

位移超出 C 中類型的寬度

[英]bits shift exceeding width of type in C

我有一個名為 vpn 的 uint64_t 變量,我試圖獲得它的左 9 位。 我知道 vpn 是 45 位長,所以我嘗試了以下操作:

uint64_t nineMSB = (vpn & (511 << 36)) >> 36;

但我收到以下警告:

left shift count >= width of type

這是為什么? 511 是二進制的 9 個 1,所以 511 << 36 應該給我 45 位,我正在用 uint64_t 進行 AND 運算,所以結果不應超過 64 位。

謝謝!

常量511類型為int 您的系統很可能有一個 32 位的int ,因此這意味着您將一個值移動的量大於其位長度。 這樣做會觸發未定義的行為

這是由C 標准的第 6.5.7p3 節關於按位移位運算符規定的:

對每個操作數執行整數提升。 結果的類型是提升的左操作數的類型。 如果右操作數的值為負或大於或等於提升的左操作數的寬度,則行為未定義。

您可以通過在常量上使用ULL后綴來解決此問題,這將賦予它類型unsigned long long ,保證長度為 64 位。

uint64_t nineMSB = (vpn & (511ULL << 36)) >> 36;

沒有任何后綴的整數常量具有int類型。 在許多系統上int是 32 位長,但它也可以只有 16 位長(avr 端口)。

uint64_t foo(uint64_t vpn)
{
    uint64_t nineMSB = (vpn & (511ULL << 36)) >> 36;
    return nineMSB;
}

uint64_t foo1(uint64_t vpn)
{
    uint64_t nineMSB = (vpn & ((uint64_t)511 << 36)) >> 36;
    return nineMSB;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM