Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C x^=x&-x;其中x是无符号整数?_C_Language Lawyer - Fatal编程技术网

C x^=x&-x;其中x是无符号整数?

C x^=x&-x;其中x是无符号整数?,c,language-lawyer,C,Language Lawyer,由于-运算符被应用于x而未签名,此函数是否会调用未定义的行为?我查了一下标准,找不到解释 unsigned foo(unsigned x) { return x ^= x & -x; } 是的 编辑 IMO唯一的解释是,它被提升为较大的有符号整数大小,然后转换为无符号整数 如果它被提升为更大的整数大小,如果没有更大的有符号整数类型会发生什么?此表达式的行为定义良好 允许使用类似于x=x+1的构造,因为在计算所有其他子表达式之前,x不会被赋值。在这种情况下也是如此 -x也没有问题

由于
-
运算符被应用于
x
未签名,此函数是否会调用未定义的行为?我查了一下标准,找不到解释

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

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


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

此表达式的行为定义良好

允许使用类似于
x=x+1
的构造,因为在计算所有其他子表达式之前,
x
不会被赋值。在这种情况下也是如此

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

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

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

因此,由于未发生升级,因此类型在整个表达式中保持
无符号。尽管标准中没有明确规定,
-x
实际上与
0-x
相同

对于将
INT\u MIN
传递到此函数的特定情况,它的类型为
INT
,并且超出了
无符号的范围,因此在传递到此函数时会进行转换。这将导致有符号值2147483648转换为无符号值2147483648(在两个补码中恰好具有相同的表示形式,即0x8000000)。然后,当计算
-x
时,它会环绕,结果是2147483648

6.2.5类型

9有符号整数类型的非负值范围是 对应的无符号整数类型,以及每个类型中相同值的表示形式 类型相同。41)涉及无符号操作数的计算永远不会溢出, 因为无法由结果无符号整数类型表示的结果是 约化模:比可计算的最大值大一的数 由结果类型表示。
41)相同的表示和对齐要求意味着互换性 函数的参数、函数的返回值和联合的成员。

6.3转换

6.3.1.3有符号和无符号整数 1当整数类型的值转换为除
\u Bool
以外的其他整数类型时,如果 该值可以用新类型表示,但没有更改。

2否则,如果新类型是无符号的,则通过反复添加或 比新类型中可以表示的最大值多减去一个 直到值在新类型的范围内。60)

3否则,新类型已签名,且无法在其中表示值;要么 结果是定义了实现或发出了定义了实现的信号。
60)规则描述的是基于数学值的算术运算,而不是给定类型表达式的值

6.3.1.8常用算术转换 …
否则,如果具有无符号整数类型的操作数的秩大于或等于 等于另一个操作数类型的秩,然后具有 有符号整数类型转换为无符号的操作数类型 整数类型。
简而言之,
-x
不会导致未定义的行为。表达式的结果仍然是无符号的,它只是映射到定义良好的非负值。

注释不用于扩展讨论;这段对话已经结束。我100%不相信,特别是对于我问题中的最后一个案例。无论如何,谢谢你。顺便说一句,这是我的个人记录
-8
。仍然可以理解为什么它被如此频繁地DV-ted。@P_ujsupports会导致没有升级,因为
INT\u MIN
具有类型
INT
,并且将其传递给函数会导致转换为
无符号INT
void func(unsigned x) 
{
    printf("%x", -x);
}

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