右移和有符号整数

发布于 2024-12-05 19:12:09 字数 264 浏览 0 评论 0原文

在我的编译器上,以下伪代码(值替换为二进制):

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

生成一个 word ,其位字段如下所示:

(11111111 11111111 10000000 00000000)

我可以在所有平台和 C++ 编译器上依赖此行为吗?

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:

(11111111 11111111 10000000 00000000)

Can I rely on this behaviour for all platforms and C++ compilers?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

蹲在坟头点根烟 2024-12-12 19:12:10

从以下链接:

INT34-C。请勿将表达式移位负数位数或大于或等于操作数中存在的位数

不合规代码示例(右移)

E1>> E2E1 右移的 E2 位位置。如果 E1 为无符号类型,或者 E1 为有符号类型且非负值,则结果值为 E1 / 2 商的整数部分E2。如果 E1 具有有符号类型和负值,则结果值由实现定义,并且可以是算术(有符号)移位:

算术(有符号)移位

或逻辑(无符号)移位:

逻辑(无符号)移位

此不符合规定代码示例无法测试右操作数是否大于或等于提升的左操作数的宽度,从而允许未定义的行为。

unsigned int ui1;
unsigned int ui2;
unsigned int uresult;
 
/* Initialize ui1 and ui2 */
 
uresult = ui1 >> ui2;

假设右移是作为算术(有符号)移位还是逻辑(无符号)移位来实现,也可能导致漏洞。请参阅建议 INT13-C。仅对无符号操作数使用按位运算符

From the following link:

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. 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 / 2E2. If E1 has a signed type and a negative value, the resulting value is implementation defined and can be either an arithmetic (signed) shift:

Arithmetic (signed) shift

Or a logical (unsigned) shift:

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. Use bitwise operators only on unsigned operands.

君勿笑 2024-12-12 19:12:10

来自 最新的 C++20 草案

有符号整数类型的右移是算术右移,执行符号扩展。

From the latest C++20 draft:

Right-shift on signed integral types is an arithmetic right shift, which performs sign-extension.

2024-12-12 19:12:10

不,你不能依赖这种行为。负数的右移(我假设您的示例正在处理)是实现定义的。

No, you can't rely on this behaviour. Right shifting of negative quantities (which I assume your example is dealing with) is implementation defined.

逐鹿 2024-12-12 19:12:10

在 C++ 中,没有。它依赖于实现和/或平台。

在其他一些语言中,是的。例如,在 Java 中,>>运算符被精确定义为始终使用最左边的位填充(从而保留符号)。 >>>>>运算符使用 0 填充。因此,如果您想要可靠的行为,一个可能的选择是更改为另一种语言。 (尽管显然,根据您的情况,这可能不是一个选择。)

In C++, no. 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). The >>> operator fills using 0s. 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.)

无风消散 2024-12-12 19:12:10

AFAIK 整数在 C++ 中可以表示为符号量值,在这种情况下符号扩展将用 0 填充。所以你不能依赖这个。

AFAIK integers may be represented as sign-magnitude in C++, in which case sign extension would fill with 0s. So you can't rely on this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文