首页 > 解决方案 > 位移超过 C 中类型的宽度

问题描述

我有一个名为 vpn 的 uint64_t 变量,我正在尝试获取它的左 9 位。我知道 vpn 有 45 位长,所以我尝试了以下方法:

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

但我收到以下警告:

left shift count >= width of type

这是为什么?511 是二进制的 9 个,所以 511 << 36 应该给我 45 位,我正在使用 uint64_t 进行与运算,因此结果不应超过 64 位。

谢谢!

标签: coperating-systembitbit-shiftinteger-overflow

解决方案


常量511有类型int。您的系统很可能有一个 32-bit int,所以这意味着您将一个值移动一个大于其位长度的量。这样做会触发未定义的行为

这是由C 标准的第 6.5.7p3 节关于按位移位运算符规定的:

对每个操作数执行整数提升。结果的类型是提升的左操作数的类型。如果右操作数的值为负数或大于或等于提升的左操作数的宽度,则行为未定义。

您可以通过使用ULL常量上的后缀来解决此问题,这将为其unsigned long long提供保证长度至少为 64 位的类型。

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

推荐阅读