C语言中的无符号数转有符号数

4

以下代码是否能够保证运行或者是实现定义的结果?

unsigned int a = 4294967294;
signed int b = a;

gccb的值为-2

根据C99标准(§6.3.1.3/3),如果新类型是有符号类型,但值无法表示,则结果要么是实现定义的,要么会引发实现定义的信号。

2个回答

10
a值转换为signed int是由实现定义的(正如您正确提到的6.3.1.3p3所示)。例如,在某些系统上,它可能是INT_MAX(饱和转换)。

对于gcc,实现行为在此处定义:

将整数转换为带符号整数类型时的结果或引发的信号,当该值无法表示为该类型的对象时(C90 6.2.1.2、C99 6.3.1.3)。

对于转换为宽度为N的类型,该值对2^N取模以在类型范围内;不会引起信号。

http://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html


如果我使用一个较小的值,例如正整数:unsigned int a = 42; signed int b = a;,结果仍然是实现定义的吗? - user963241
4
在这种情况下,变量 a 的值可以用类型为 b 的方式表示,因此转换后的值不会改变。不涉及实现定义行为(根据6.3.1.3第1段)。 - ouah

-2

@ouah的回答告诉你它是实现定义的,但并没有解释你的实现如何产生(-2)。 我来回答:

1)您的实现似乎具有32位宽度的int类型和2的补码表示。

2)4294967294是(UINT_MAX - 1) = 0xfffffffe。

在您的实现中,(UINT_MAX - 1)将被转换为带符号整数,如下所示:

0xfffffffe被转换为~(0xfffffffe)+1=(二进制中的1)+1=二进制中的10=十进制中的2。

请注意,在此转换之前,最高有效位为1(在0xfffffffe中),因此在上述转换后,最终数字被解释为负数。 因此,在转换后得到(-2)作为您的最终答案。

希望这有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接