在C中被签名为无符号转换-它总是安全的吗?

在C中被签名为无符号转换-它总是安全的吗?

假设我有以下C代码。

unsigned int u = 1234;int i = -5678;unsigned int result = u + i;

这里正在进行什么隐式转换,这段代码对所有的值都是安全的吗?ui?(安全,从某种意义上说,即使结果在本例中,将溢出到某个巨大的正数,我可以将其转换回INT得到真正的结果。)


慕姐4208626
浏览 502回答 3
3回答

慕少森

从签名到未签名的转换不只需复制或重新解释符号值的表示。引用C标准(C99 6.3.1.3):当具有整数类型的值转换为_bool以外的另一个整数类型时,如果该值可以由新类型表示,则它将保持不变。否则,如果新类型没有符号,则通过重复添加或减去比新类型中可以表示的最大值多一个值来转换值,直到该值位于新类型的范围内为止。否则,将对新类型进行签名,并且不能在其中表示值;结果要么是实现定义的,要么引发实现定义的信号。对于现在几乎通用的两种补码表示,规则确实对应于重新解释比特。但是对于其他表示(符号和大小或1的补码),C实现仍然必须安排相同的结果,这意味着转换不能只是复制比特。例如,(无符号)-1=UINT_MAX,而不管表示形式如何。通常,C中的转换定义为在值上操作,而不是在表示上操作。要回答原来的问题:unsigned int u = 1234;int i = -5678;unsigned int result = u + i;i的值转换为无符号int,生成UINT_MAX + 1 - 5678..然后将此值添加到无符号值1234中,生成UINT_MAX + 1 - 4444.(与无符号溢出不同,签名溢出会调用未定义的行为。概括是常见的,但不是C标准所保证的-编译器的优化可能会对做出不合理假设的代码造成极大的破坏。)

POPMUISE

指圣经:添加操作将使int转换为无符号int。假设两个补码表示和大小相等的类型,位模式不会改变。从无符号int到有符号int的转换取决于实现。(但现在大多数平台上,它的工作方式可能与你预期的一样。)在不同大小的有符号和无符号组合的情况下,规则要复杂一些。
打开App,查看更多内容
随时随地看视频慕课网APP