简体   繁体   English

右移和有符号整数

[英]Right shift and signed integer

On my compiler, the following pseudo code (values replaced with binary): 在我的编译器上,以下伪代码(用二进制替换的值):

sint32 word = (10000000 00000000 00000000 00000000);
word >>= 16;

produces a word with a bitfield that looks like this: 使用如下所示的位域生成一个word

(11111111 11111111 10000000 00000000)

My question is, can I rely on this behaviour for all platforms and C++ compilers? 我的问题是,我可以依赖所有平台和C ++编译器的这种行为吗?

From the following link: 从以下链接:
INT34-C. INT34-C。 Do not shift an expression by a negative number of bits or by greater than or equal to the number of bits that exist in the operand 不要将表达式移位负数位或大于或等于操作数中存在的位数

Noncompliant Code Example (Right Shift) 不合规的代码示例(右移)
The result of E1 >> E2 is E1 right-shifted E2 bit positions. E1 >> E2的结果是E1右移E2位的位置。 If E1 has an unsigned type or if E1 has a signed type and a nonnegative value, the value of the result is the integral part of the quotient of E1 / 2 E2 . 如果E1具有无符号类型或者E1具有有符号类型和非负值,则结果的值是E1 / 2 E2的商的整数部分。 If E1 has a signed type and a negative value, the resulting value is implementation defined and can be either an arithmetic (signed) shift: 如果E1具有带符号类型和负值,则结果值是实现定义的,可以是算术(带符号)移位:
算术(签名)移位
or a logical (unsigned) shift: 或逻辑(无符号)转变:
逻辑(无符号)转换
This noncompliant code example fails to test whether the right operand is greater than or equal to the width of the promoted left operand, allowing undefined behavior. 这个不合规的代码示例无法测试右操作数是否大于或等于提升的左操作数的宽度,从而允许未定义的行为。

unsigned int ui1;
unsigned int ui2;
unsigned int uresult;

/* Initialize ui1 and ui2 */

uresult = ui1 >> ui2;

Making assumptions about whether a right shift is implemented as an arithmetic (signed) shift or a logical (unsigned) shift can also lead to vulnerabilities. 假设右移是实现为算术(带符号)移位还是逻辑(无符号)移位也可能导致漏洞。 See recommendation INT13-C. 见建议INT13-C。 Use bitwise operators only on unsigned operands . 仅在无符号操作数上使用按位运算符

No, you can't rely on this behaviour. 不,你不能依赖这种行为。 Right shifting of negative quantities (which I assume your example is dealing with) is implementation defined. 负数量的右移(我假设你的例子正在处理)是实现定义的。

In C++, no. 在C ++中,没有。 It is implementation and/or platform dependent. 它取决于实现和/或平台。

In some other languages, yes. 在其他一些语言中,是的。 In Java, for example, the >> operator is precisely defined to always fill using the left most bit (thereby preserving sign). 例如,在Java中,>>运算符被精确定义为始终使用最左边的位填充(从而保留符号)。 The >>> operator fills using 0s. >>>运算符使用0填充。 So if you want reliable behavior, one possible option would be to change to a different language. 因此,如果您需要可靠的行为,一种可能的选择是更改为其他语言。 (Although obviously, this may not be an option depending on your circumstances.) (虽然很明显,根据您的具体情况,这可能不是一种选择。)

AFAIK integers may be represented as sign-magnitude in c++, in which case sign extension would fill with 0s. AFAIK整数可以用c ++表示为符号幅度,在这种情况下,符号扩展将填充0。 So you can't rely on this. 所以你不能依赖这个。

From the latest C++20 draft : 最新的C ++ 20草案

Right-shift on signed integral types is an arithmetic right shift, which performs sign-extension. 有符号整数类型的右移是算术右移,它执行符号扩展。

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

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