Dan*_*her 23
标准说(n1570中为6.5.7):
3对每个操作数执行整数提升.结果的类型是提升的左操作数的类型.如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义.
4 E1 << E2的结果是E1左移E2位位置; 腾出的位用零填充.如果E1具有无符号类型,则结果的值为E1×2 E2,比结果类型中可表示的最大值减少一个模数.如果E1具有带符号类型和非负值,并且E1×2 E2可在结果类型中表示,那么这就是结果值; 否则,行为未定.
5 E1 >> E2的结果是E1右移E2位的位置.如果E1具有无符号类型或者E1具有有符号类型和非负值,则结果的值是E1/2 E2的商的整数部分.如果E1具有有符号类型和负值,则生成的值是实现定义的.
移位uint64_t小于64位的距离完全是由标准限定.
由于long long必须至少为64位long long,如果结果不溢出,则非负值的标准定义小于64位的移位值.
但是请注意,如果你编写一个适合32位的文字,例如uint64_t s = 1 << 32@drhirsch推测的那样,你实际上并没有移动64位值而是移位32位值.这是未定义的行为.最常见的结果是移位shift_distance % 320或0,具体取决于硬件的作用.
C 标准要求班次正常工作。特定的错误编译器可能具有您描述的缺陷,但这是错误行为。
这是一个测试程序:
#include <stdio.h>
#include <inttypes.h>
int main(void)
{
    uint64_t x = 1;
    for (int i = 0; i < 64; i++)
        printf("%2d: 0x%.16" PRIX64 "\n", i, (x << i));
    return 0;
}
这是运行带有 GCC 4.1.2 的 RHEL 5 的 i686 机器、x86/64 机器(也运行 RHEL 5 和 GCC 4.1.2)和 x86/64 Mac(运行 Mac OS X 10.7。 3 与 GCC 4.7.0)。由于这是预期的结果,我得出结论,在 32 位机器上没有必要的问题,并且 GCC 至少自 GCC 4.1.2 以来没有出现任何此类错误(并且可能从未出现过此类错误)。
 0: 0x0000000000000001
 1: 0x0000000000000002
 2: 0x0000000000000004
 3: 0x0000000000000008
 4: 0x0000000000000010
 5: 0x0000000000000020
 6: 0x0000000000000040
 7: 0x0000000000000080
 8: 0x0000000000000100
 9: 0x0000000000000200
10: 0x0000000000000400
11: 0x0000000000000800
12: 0x0000000000001000
13: 0x0000000000002000
14: 0x0000000000004000
15: 0x0000000000008000
16: 0x0000000000010000
17: 0x0000000000020000
18: 0x0000000000040000
19: 0x0000000000080000
20: 0x0000000000100000
21: 0x0000000000200000
22: 0x0000000000400000
23: 0x0000000000800000
24: 0x0000000001000000
25: 0x0000000002000000
26: 0x0000000004000000
27: 0x0000000008000000
28: 0x0000000010000000
29: 0x0000000020000000
30: 0x0000000040000000
31: 0x0000000080000000
32: 0x0000000100000000
33: 0x0000000200000000
34: 0x0000000400000000
35: 0x0000000800000000
36: 0x0000001000000000
37: 0x0000002000000000
38: 0x0000004000000000
39: 0x0000008000000000
40: 0x0000010000000000
41: 0x0000020000000000
42: 0x0000040000000000
43: 0x0000080000000000
44: 0x0000100000000000
45: 0x0000200000000000
46: 0x0000400000000000
47: 0x0000800000000000
48: 0x0001000000000000
49: 0x0002000000000000
50: 0x0004000000000000
51: 0x0008000000000000
52: 0x0010000000000000
53: 0x0020000000000000
54: 0x0040000000000000
55: 0x0080000000000000
56: 0x0100000000000000
57: 0x0200000000000000
58: 0x0400000000000000
59: 0x0800000000000000
60: 0x1000000000000000
61: 0x2000000000000000
62: 0x4000000000000000
63: 0x8000000000000000
| 归档时间: | 
 | 
| 查看次数: | 13487 次 | 
| 最近记录: |