x ^= x & -x; 其中 x 是一个无符号整数调用 UB?

P__*_*J__ -4 c language-lawyer

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

unsigned foo(unsigned x)
{
    return x ^= x & -x;
}
Run Code Online (Sandbox Code Playgroud)

海事组织是的。

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

int main(void)
{
    func(INT_MIN);
}
Run Code Online (Sandbox Code Playgroud)

IMO唯一的解释是它被提升为更大的有符号整数大小,然后转换为无符号整数。

如果将其提升为更大的整数大小,如果没有更大的有符号整数类型会发生什么?

dbu*_*ush 6

这个表达式的行为是明确定义的。

x = x + 1允许类似于 的构造,因为x在评估所有其他子表达式之前不会为其分配值。这同样适用于这种情况。

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

关于一元运算符的C 标准第 6.5.3.3p3 节-规定:

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

因此,由于没有发生提升,该类型unsigned在整个表达式中保持不变。虽然标准中没有明确说明,但-x实际上与0 - x.

对于INT_MIN传递给这个函数的特定情况,它有类型int并且在 的范围之外unsigned,所以在传递给函数时会被转换。这导致有符号值 -2,147,483,648 被转换为无符号值 2,147,483,648(在二进制补码中恰好具有相同的表示,即 0x80000000)。然后当-x被评估时,它环绕产生 2,147,483,648。