使用条件运算符比较两个无符号值时的有符号无符号不匹配

使用条件运算符比较两个无符号值时的有符号无符号不匹配,第1张

概述我有以下C代码: unsigned int a;unsigned char b, c;void test(void) { if (a < b) return; if (a < (b ? b : c)) return;} 当我编译它(使用Microsoft cl,来自MS SDK 7,-W3警告级别)时,第二次比较会发出警告:C4018,签名/无 我有以下C代码:
unsigned int a;unsigned char b,c;voID test(voID) {    if (a < b)        return;    if (a < (b ? b : c))        return;}

当我编译它(使用Microsoft cl,来自MS SDK 7,-W3警告级别)时,第二次比较会发出警告:C4018,签名/无符号不匹配.第一次比较没有发出警告.

我已经检查了MS docs on the conditional operator并且他们说如果两个 *** 作数是相同的类型,结果将是相同的类型,所以它应该作为第一个比较.我错过了什么吗?

UPD:用gcc -Wall -Wextra -pedantic进行测试,没有任何警告.

解决方法 这可能是由于算术转换规则:首先,任何整数类型的转换等级小于int(例如unsigned char)将提升为int或unsigned int.

结果是int还是unsigned int不会(直接)依赖于原始类型的签名,但是它的范围:int甚至用于无符号类型,只要可以表示所有值,这就是unsigned char的情况.在主流架构上.

其次,由于两个 *** 作数最终具有相同的转换等级,但是一个是无符号的,另一个 *** 作数也将转换为无符号类型.

在语义上,您的表达式读取

a < (unsigned int)(int)b

a < (unsigned int)(b ? (int)b : (int)c)

编译器显然足够聪明,可以注意到第一种情况不会导致问题,但第二种情况则失败.

Steve Jessop的评论很好地解释了这可能发生的原因:

I would imagine that in the first case the compiler thinks,“I have a comparison operator whose operand types are unsigned int and unsigned char. No need for a warning,Now let’s apply promotion followed by usual conversion”.

In the second case it thinks,“I have a comparison operator whose operand types are unsigned int and int (which I derived as the type of the conditional Expression on the RHS). Best warn about that!”.

总结

以上是内存溢出为你收集整理的使用条件运算符比较两个无符号值时的有符号/无符号不匹配全部内容,希望文章能够帮你解决使用条件运算符比较两个无符号值时的有符号/无符号不匹配所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1242228.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存