其他分享
首页 > 其他分享> > c – 如果计数大于类型的宽度,是右移未定义的行为吗?

c – 如果计数大于类型的宽度,是右移未定义的行为吗?

作者:互联网

我刚检查了C标准.看来以下代码不应该是undefined behavior

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

并从标准:

The value 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 non-negative
value, the value of the result is the integral part of the quotient of
E1/2^E2.
If E1 has a signed type and a negative value, the resulting
value is implementation-defined.

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

GCC为代码段提供以下警告,res为67108863:

warning: right shift count >= width of type

我还检查了GCC发出的汇编代码.它只是调用SHRL,以及针对SHRL的英特尔指令文件,res不是ZERO.

那么这是否意味着GCC没有在英特尔平台上实现标准行为?

解决方法:

第5节中的draft C++ standard第1段中的Shift运算符表示(强调我的):

The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.

因此,如果unsigned int是32位或更少,那么这是未定义的,这正是gcc给你的警告.

标签:c,undefined-behavior,assembly,gcc,standards
来源: https://codeday.me/bug/20190916/1808245.html