簡體   English   中英

移位計數大於類型的寬度

[英]shift count greater than width of type

我有一個函數,它需要一個int data_length並執行以下操作:

unsigned char *message = (unsigned char*)malloc(65535 * sizeof(char));
message[2] = (unsigned char)((data_length >> 56) & 255);

我得到以下內容:

warning: right shift count >= width of type [-Wshift-count-overflow]
   message[2] = (unsigned char)((data_length >> 56) & 255);

該程序可以按預期工作,但是如何刪除編譯器警告(不禁用它)? 類似的問題似乎沒有使用變量作為要插入的數據,因此似乎解決方案是將其強制轉換為int或此類。

標准不允許移位大於所討論類型的位寬的量,並且這樣做會引起未定義的行為

C標准的 6.5.7p3節中有關於位移位運算符的詳細信息。

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

如果該程序似乎正在運行,則很幸運。 您可以對程序進行不相關的更改,也可以僅在其他計算機上構建它,然后突然一切都停止了。

如果data_length的大小為32位或更小,則右移56位太大。 您只能平移0-31。

問題很簡單。 當使用data_length進行無符號化(因為負長度幾乎沒有意義)時,您將其用作int 為了能夠移位56位,該值必須至少為56 57位寬。 否則,行為是不確定的。

在實踐中,已知處理器會做很多不同的事情。 在一個例子中,將32位值右移32位將清除變量。 在另一個值中,該值移位了0位( 32 % 32 !)。 然后,在某些情況下,也許處理器認為它是無效的操作碼,而OS終止了該進程。

簡單的解決方案:聲明uint64_t data_length


如果你真的有自己限制在32位數據類型,那么你可以指定0到這些字節即表示最顯著字節。 或者只是在轉換前unsigned long longuint64_t轉換為uint64_tunsigned long long

暫無
暫無

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

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