我现在找不到链接,但只要int
为正,只需将unsigned type
传递给需要int
的函数即可。 (并且属于未签名的范围);我得到了一个警告,这就是我要问的原因
假设没有演员阵容
假设unsigned integers
值适合int
范围?,反之亦然
答案 0 :(得分:4)
将有符号整数传递给期望无符号整数的函数具有明确定义的行为。如果参数值在参数类型的范围内,则有一个简单的转换;价值保持不变。如果参数值超出该范围,则将通过丢弃高位来有效地转换它。
当且仅当该行为与应用程序的行为方式一致时,这是可以的。
将无符号整数传递给期望有符号整数的函数具有明确定义的行为如果该值在参数类型的范围内。如果不是,那么隐式转换将产生实现定义的结果(或者,原则上,它可以引发实现定义的信号,但我不知道任何实现那样做)。通常,结果相当于丢弃高位,或者将无符号值解释为有符号值(将高位作为符号位处理),但语言无法保证这一点。对于无符号到签名的转换,最好确保该值在目标类型的范围内。
很多时候(但并不总是)这样的转换表明参数应该与第一个参数的类型相同。
这一切都假定函数是用原型正确声明的,因此编译器在看到调用时知道函数期望的类型。如果没有原型,或者函数是可变参数(如printf
),那么你需要更加小心。没有转化,但您可以依赖int
和unsigned int
可互换来获取范围内的值。 (但依赖于它并不是一个好主意;最好确保你传递的参数是预期的类型。)
答案 1 :(得分:1)
这可以分为两个不同的问题:
它会起作用吗?
是的,可能。所有变量值都只是位序列,在某种程度上,您可以快速松散地使用类型,并且如果您小心,仍然可以获得正确的结果。
我应该这样做吗?
不,有几个原因:
你不应该养成忽视警告的习惯。他们有一个原因:他们让你知道结果可能不是你所期望的。你应该尽可能多地努力正确地解决它们,就像错误一样。
您的代码将难以理解未来的读者。您应尽可能使您的代码对未来的读者(包括您自己)易于理解和维护。部分原因是使用了正确的类型。如果您需要使用期望某种类型的函数,并且由于某种原因您必须为其提供不同类型的数据,则应该将其强制转换以使您的意图清晰。
理解和调试代码是很困难的。当你在代码中做出隐含的假设时,你只会让自己变得更难。尝试重构它以使用您想要执行的操作所需的类型。您当前的假设是您的值始终为正,始终在有符号整数的范围内。如果违反了这些条件中的任何一个(您应该认为这是可能的,因为没有代码是完美的),那么您的代码将出现意外行为。在使用期望unsigned int的值之前,您应该为这些条件添加一些检查,然后显式地转换它。这将通过捕获错误使调试更容易,和使您的意图对未来的读者清楚。
答案 2 :(得分:0)
没错。您可以通过这种方式确定您的应用是否安全,并且所有编译器都会警告您。只要价值保持在您期望的范围内,就不会出现意外情况。
答案 3 :(得分:0)
只要源的当前值符合目标的允许范围,两个方向都可以。一些工具或编译器(gcc:btn_uploader.startup();
)仍然警告这个有充分的理由:引起你的注意。
如果您完全确定值适合,只需使用强制转换来抑制警告。但是在该行(或之前)添加注释为什么实际使用该转换。有些编辑会在评论中突出显示特殊关键字(例如-Wconversion
),因此您会看到有些内容需要注意。
一旦值不合适,您就会展示 undefined bahaviour ,所以请注意!