【问题标题】:left shift count >= width of type - adding UL or casting individually does not fix the issue左移计数 >= 类型宽度 - 添加 UL 或单独铸造并不能解决问题
【发布时间】:2016-12-14 04:13:44
【问题描述】:

我正在尝试做一些非常简单的事情,但我收到了这个警告。这是我所拥有的:

#define VERSION ( (unsigned long)( (CORE_ID << 32) + (PROTO_ID << 24) + (VERSION_ID << 16) + (RELEASE_ID << 8) + (HOTFIX_ID) ) )

unsigned long vern = VERSION;

我不断收到左移计数 >= 类型宽度的警告,但我没有做任何事情来帮助摆脱此消息。我尝试单独转换为 unsigned int 但这也无济于事。 所有 ID 都只是数字的常规 #define。

我尝试将 UL 添加到每个数字的末尾,但这也无济于事。我知道这意味着我的移位导致溢出,但考虑到一切都被定义为 UL,我不确定如何补救。 我不确定我做错了什么,感谢任何帮助。

非常感谢

【问题讨论】:

  • CORE_ID的类型是什么?
  • CORE_ID &lt;&lt; 32 --> 1ull*CORE_ID &lt;&lt; 32,同样适用于PROTO_ID。更好的是,发布所有与此相关的#define,例如CORE_ID等。
  • #define HW 80 #define REV 5 #define CORE_ID 7 #define PROTO_ID 7 #define VERSION_ID (HW+REV) #define RELEASE_ID 07 #define HOTFIX_ID 01
  • “尝试将 UL 添加到每个号码的末尾”不清楚。发布失败的代码比描述失败的代码更有用。
  • 试试#define VERSION ( (1ull*CORE_ID &lt;&lt; 32) + (1ull*PROTO_ID &lt;&lt; 24) + (1ul*VERSION_ID &lt;&lt; 16) + (1ul*RELEASE_ID &lt;&lt; 8) + (1ul*HOTFIX_ID) )

标签: c++


【解决方案1】:

所有计算后的演员都没有帮助;问题是被转移的类型太小了,答案是增加它们的大小。我不想全部打出来,但这是模式:

#define VERSION ((unsigned long)CORE_ID << 32)

CORE_ID 转换为unsigned long 可能会解决问题。如果unsigned long 太小(即,它是 32 位宽,这是允许的最小大小),则将其更改为 unsigned long long。在原始代码中,将这些内容中的每一个都转换为unsigned long;一旦它们都具有 unsigned long 类型,组合它们的结果也将是 unsigned long,并且您将不需要初始转换。

【讨论】:

  • 或者使用uint64_t(如果合适,用UINT64_C宏声明常量),因为字段的性质是它必须是64位宽,所以对没有官方大小的类型进行处理看起来很傻。
  • unsigned long long 会更好。在 64 位 Windows 上,unsigned long 仍然是 32 位,标准只规定 unsigned long long 必须至少为 64 位
  • @ShadowRanger - uint64_t 不需要存在。为了获得最大的便携性,uint_fast64_tuint_least64_t 将是更好的选择。
  • @PeteBecker:是的。我从来没有遇到过没有它的系统,但是,是的,为了获得最大的可移植性,说明您的最低要求并让编译器处理它是好的。
猜你喜欢
  • 1970-01-01
  • 2014-06-22
  • 1970-01-01
  • 1970-01-01
  • 2023-02-05
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多