簡體   English   中英

移位計數 >= 64 位但不是 32 位的類型警告寬度

[英]shift count >= width of type warning for 64 bit but not 32 bit

我收到 test1 的“班次計數 >= 類型寬度”警告,但 test3 沒有收到同樣的警告。 所有測試似乎都有效,並且鑄造擺脫了警告。 但是,我不明白為什么我沒有收到關於 test3 的類似警告。

test1 和 test2 在我的機器上是 64 位長類型,而 test3 和 test4 在我的機器上是 32 位 int 類型。 我使用與此類似的代碼來打包/解包數據以通過網絡發送。 我重寫了它以適應這個問題。

unsigned char arr1[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
unsigned char arr2[4] = {0xFF, 0xFF, 0xFF, 0xFF};
long test1;
long test2;
int test3;
int test4;

// Gives warning: shift count >= width of type
test1 = (arr1[0] << 56) | (arr1[1] << 48) | (arr1[2] << 40) | (arr1[3] << 32)
    | (arr1[4] << 24) | (arr1[5] << 16) | (arr1[6] << 8) | arr1[7];
printf("Test 1: %lX\n", test1);

// No warning
test2 = ((long)arr1[0] << 56) | ((long)arr1[1] << 48) | ((long)arr1[2] << 40)
    | ((long)arr1[3] << 32) | ((long)arr1[4] << 24) | ((long)arr1[5] << 16)
    | ((long)arr1[6] << 8) | (long)arr1[7];
printf("Test 2: %lX\n", test2);

// No warning. Shouldn't this give a warning?
test3 = (arr2[0] << 24) | (arr2[1] << 16) | (arr2[2] << 8) | arr2[3];
printf("Test 3: %X\n", test3);

// No warning
test4 = ((int)arr2[0] << 24) | ((int)arr2[1] << 16) | ((int)arr2[2] << 8)
    | (int)arr2[3];
printf("Test 4: %X\n", test4);

由於integer 促銷,案例 3 中沒有警告。

一般來說,當在表達式中使用小於int的類型時,它首先被提升為int 例如,當您這樣做時:

arr2[0] << 24

arr2[0]的類型為unsigned char ,但該值首先被提升為int ,然后被提升的值被移位。 所以case 3和case 4其實是一樣的。

這里要注意的一件事是,由於升級為有符號類型,您可能會將值為 1 的位移入符號位。 這樣做會觸發未定義的行為

處理此問題的最安全方法是在移位之前將每個值強制轉換為適當大小的無符號類型,並且應將結果分配給正確的無符號類型。 另請注意特定於大小的printf格式說明符的宏。

unsigned char arr1[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
unsigned char arr2[4] = {0xFF, 0xFF, 0xFF, 0xFF};
uint64_t test2;
uint32_t test4;

test2 = ((uint64_t)arr1[0] << 56) | ((uint64_t)arr1[1] << 48)
      | ((uint64_t)arr1[2] << 40) | ((uint64_t)arr1[3] << 32)
      | ((uint64_t)arr1[4] << 24) | ((uint64_t)arr1[5] << 16)
      | ((uint64_t)arr1[6] << 8)  | (uint64_t)arr1[7];
printf("Test 2: %" PRIX64 "\n", test2);

test4 = ((uint32_t)arr2[0] << 24) | ((uint32_t)arr2[1] << 16) 
      | ((uint32_t)arr2[2] << 8)  | (uint32_t)arr2[3];
printf("Test 4: %" PRIX32 "\n", test4);

暫無
暫無

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

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