x ^ = x&是吗?-X;其中x是一个无符号整数调用UB? [英] Does x ^= x & -x; where x is an unsigned integer invoke UB?

查看:64
本文介绍了x ^ = x&是吗?-X;其中x是一个无符号整数调用UB?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于将-运算符应用于 unsigned x ,此函数是否调用未定义的行为?我搜索了标准,却找不到解释.

Does this function invoke undefined behavior due to the - operator being applied to x which is unsigned? I searched the standard and couldn't find an explanation.

unsigned foo(unsigned x)
{
    return x ^= x & -x;
}

IMO是.

void func(unsigned x) 
{
    printf("%x", -x);
}

int main(void)
{
    func(INT_MIN);
}

IMO 的唯一解释是将其提升为更大的有符号整数,然后转换为无符号.

IMO The only explanation is that it was promoted to larger signed integer size then converted to unsigned.

如果将其提升为更大的整数大小,那么如果没有更大的带符号整数类型会怎样?

If it is promoted to larger integer size, what will happen if there is no larger signed integer type?

推荐答案

此表达式的行为已得到很好的定义.

The behavior of this expression is well defined.

类似于 x = x + 1 的构造,因为在所有其他子表达式都被撤消之前,不会给 x 赋值.在这种情况下也是如此.

Constructs similar to x = x + 1 are allowed because x isn't assigned a value until all other subexpressions are evaulated. The same applies in this case.

-x 也没有问题,因为表达式具有无符号类型,因此具有定义良好的环绕行为,而不是溢出.

There is also no problem with -x because the expression has unsigned type and thus has well defined wraparound behavior as opposed to overflowing.

C标准的6.5.3.3p3节关于一元-运算符状态:

Section 6.5.3.3p3 of the C standard regarding the unary - operator states:

一元-运算符的结果为其(提升的)操作数的负数.对操作数执行整数提升,并且结果具有提升的类型.

The result of the unary - operator is the negative of its (promoted) operand. The integer promotions are performed on the operand, and the result has the promoted type.

因此,由于没有提升发生,所以该类型在整个表达式中都保持 unsigned .尽管未在标准中明确说明,但 -x 实际上与 0-x 相同.

So since no promotion occurs the type remains unsigned throughout the expression. Though not explicitly stated in the standard, -x is effectively the same as 0 - x.

对于将 INT_MIN 传递给此函数的特定情况,它的类型为 int ,并且在 unsigned 范围之外,因此传递给函数时将对其进行转换.这导致有符号值-2,147,483,648被转换为无符号值2,147,483,648(以二进制补码形式表示的值相同,即0x80000000).然后,当对 -x 求值时,它会回绕,结果为2,147,483,648.

For the specific case of INT_MIN being passed to this function, it has type int and is outside of the range of unsigned, so it is converted when passed to the function. This results in the signed value -2,147,483,648 being converted to the unsigned value 2,147,483,648 (which in two's complement happen to have the same representation, i.e. 0x80000000). Then when -x is evaluated, it wraps around resulting in 2,147,483,648.

这篇关于x ^ = x&是吗?-X;其中x是一个无符号整数调用UB?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆