简体   繁体   English

msvc中按位左移的操作与Linux gcc不同吗?

[英]bitwise operation left shift in msvc is diffrent from linux gcc?

On Linux using GCC, 1UL<<44 is 0x100000000000 在使用GCC的Linux上, 1UL<<440x100000000000

But on Windows using MSVC, 1UL<<44 is 0 但是在使用MSVC的Windows上, 1UL<<440

I am so confused. 我感到很困惑。

Does this show that on Windows a left shift can not shift more than 32 bits? 这是否表明在Windows上左移不能超过32位?

In Windows unsigned long s are 32 bits wide. 在Windows中, unsigned long的宽度为32位。 This is due to the unfortunate APIs always expecting unsigned longs to be synonymous with 32 bits, (4 bytes) whereas in Unixen having unsigned longs were equally incorrectly often assumed to be of suitable size for storing a pointer. 这是由于不幸的API总是期望无符号长为32位(4字节)的同义词,而在Unixen中,无符号长常被错误地假定为适合存储指针的大小。 Hence in Unixen it made sense to use 64 bits unsigned longs and in Windows there is no choice but to keep them 32 bits. 因此,在Unixen中,使用64位无符号长整数是有意义的,而在Windows中,别无选择,只能将它们保留32位。

Of course it would have always be correct to just use uint32_t and uintptr_t respectively for these, but lots of code was written before those were standardized. 当然,分别对它们使用uint32_tuintptr_t总是正确的,但是在对它们进行标准化之前就编写了许多代码。


Notice that the standard says that the behaviour is undefined if the shift amount is negative,, or greater than or equal to the width of shifted type so on Windows 1UL << 32 has undefined behaviour. 请注意,该标准说,如果移位量为负,或者大于或等于移位类型的宽度,则行为是不确定的,因此在Windows 1UL << 32具有不确定的行为。 This is because there are hardware that zero the target if a wide shift happens, hardware that aborts and hardware that only consider the shifts modulo 32, ie in this case executing 1UL << 0 which of course equals 1. So since this operation makes no sense in any portable program some C compilers can happily assume that they never happen. 这是因为,如果发生大范围移位,则存在将目标置零的硬件,中止的硬件和仅考虑以32为模的移位的硬件,即,在这种情况下,执行1UL << 0当然等于1。在任何可移植程序中,某些C编译器可以很高兴地认为它们永远不会发生。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM