以下代码是否能够保证运行或者是实现定义的结果?
unsigned int a = 4294967294;
signed int b = a;
gcc
上b
的值为-2
。
根据C99标准(§6.3.1.3/3),如果新类型是有符号类型,但值无法表示,则结果要么是实现定义的,要么会引发实现定义的信号。
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
@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)作为您的最终答案。
希望这有所帮助。
unsigned int a = 42; signed int b = a;
,结果仍然是实现定义的吗? - user963241a
的值可以用类型为b
的方式表示,因此转换后的值不会改变。不涉及实现定义行为(根据6.3.1.3第1段)。 - ouah