为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕姐4208626 2019-06-20 11:21:34
在C中被签名为无符号转换-它总是安全的吗?假设我有以下C代码。unsigned int u = 1234;int i = -5678;unsigned int result = u + i;这里正在进行什么隐式转换,这段代码对所有的值都是安全的吗?u和i?(安全,从某种意义上说,即使结果在本例中,将溢出到某个巨大的正数,我可以将其转换回INT得到真正的结果。)
查看完整描述

3 回答

?
慕少森

TA贡献2019条经验 获得超9个赞

从签名到未签名的转换只需复制或重新解释符号值的表示。引用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标准所保证的-编译器的优化可能会对做出不合理假设的代码造成极大的破坏。)


查看完整回答
反对 回复 2019-06-20
?
POPMUISE

TA贡献1765条经验 获得超5个赞

圣经:

  • 添加操作将使int转换为无符号int。
  • 假设两个补码表示和大小相等的类型,位模式不会改变。
  • 从无符号int到有符号int的转换取决于实现。(但现在大多数平台上,它的工作方式可能与你预期的一样。)
  • 在不同大小的有符号和无符号组合的情况下,规则要复杂一些。


查看完整回答
反对 回复 2019-06-20
  • 3 回答
  • 0 关注
  • 500 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信