这个大型应用程序有一个内存池库,它在内部使用treap来存储内存节点。 treap是使用cpp宏实现的,可以找到完整的文件trp.h here。当我尝试编译应用程序时,我收到以下编译器警告:
warning: this decimal constant is unsigned only in ISO C90
通过删除部分宏代码并使用反复试验,我终于找到了罪魁祸首:
#define trp_prio_get(a_type, a_field, a_node) \
(2654435761*(uint32_t)(uintptr_t)(a_node))
我不确定那个奇怪的数字在那里做什么,但我认为这是有充分理由的,所以我只想不管它。我确实想修复警告 - 任何想法为什么编译器说它只在ISO C90中是无符号的?
编辑:我正在使用gcc-4.1
答案 0 :(得分:6)
2654435761是对应于2 ^ 32的黄金比率数字。
在Knuth的“计算机艺术”中 编程“,第6.4节,a 乘法散列方案是 作为一种写哈希的方式介绍 功能。密钥乘以 黄金比例为2 ^ 32(2654435761) 产生哈希结果。
自2654435761和2 ^ 32没有 共同的共同因素, 乘法产生完整 将密钥映射到散列结果 没有重叠。这种方法效果很好 好吧,如果键值很小。 如果出现错误的哈希结果 密钥在高位有所不同。原样 在所有乘法中都是真的, 高位数的变化不会 影响的低位数 乘法结果。
答案 1 :(得分:6)
尝试用
替换该号码2654435761u
强制它无符号。
答案 2 :(得分:2)
我认为它是无符号的,因为它大于2,147,483,647,这是长有符号整数的最大大小,所以为了避免环绕,它将它视为无符号并发出警告。
答案 3 :(得分:2)
问题是这个常数2654435761
大于2 ^ 31。这意味着对于较旧的编译器,它实际上将变为负值作为有符号常量。
现在,在这种情况下并不重要,因为由于乘以无符号值,它将被转换回无符号,并且正确的事情将会发生。