Warm tip: This article is reproduced from serverfault.com, please click

c++-如果计数大于类型的宽度,是否会出现右移未定义的行为?

(c++ - Is right shift undefined behavior if the count is larger than the width of the type?)

发布于 2013-09-20 13:39:35

我刚刚检查了C ++标准。似乎以下代码不应为未定义行为

unsigned int val = 0x0FFFFFFF;
unsigned int res = val >> 34;  // res should be 0 by C++ standard,
                               // but GCC gives warning and res is 67108863

从标准来看:

E1 >> E2的值是E1右移E2位的位置。如果E1具有无符号类型,或者E1具有带符号类型且非负值,则结果的值是E1 / 2 ^ E2商的整数部分。如果E1具有带符号的类型和负值,则结果值由实现定义。

根据标准,由于34不是负数,因此变量res将为0。

GCC针对代码段发出以下警告,并且res67108863

警告:右移计数> =类型的宽度

我还检查了GCC发出的汇编代码。它只是调用SHRL,而英特尔指令文档中的SHRLres则不是零。

那么,这是否意味着GCC无法在Intel平台上实现标准行为?

Questioner
ZijingWu
Viewed
11
Shafik Yaghmour 2014-02-08 13:01:15

草案C ++标准在部分5.8 移位运算符在第1说(重点矿山):

结果的类型是提升后的左操作数的类型。如果右操作数为负或大于或等于提升后的左操作数的位长度,则该行为是不确定的

因此,如果unsigned int类型32 bits以下那么这是未定义而这正是该警告gcc是给你的。