[英]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.