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唯一的解释是它被提升为更大的有符号整数大小,然后转换为无符号整数。
如果将其提升为更大的整数大小,如果没有更大的有符号整数类型会发生什么?
这个表达式的行为是明确定义的。
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。