解释整数与促销的比较 [英] Explain integer comparison with promotion

查看:94
本文介绍了解释整数与促销的比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试了解c ++应用程序中的整数提升和比较是如何工作的.

I'm trying to understand how integer promotion and comparison in and c++ application works.

#include <cstdint>

int main(void)
{
    uint32_t foo  = 20;
    uint8_t a = 2;
    uint8_t b = 1;
    uint8_t c = 5;

    if(foo == b*c) {}

    if(foo == a) {}

    if(foo == a + c) {}

    if(foo == a + b*c) {}

    return 0;
}

仅在最后一次比较时,我得到一个编译器警告:有符号和无符号整数表达式[-Wsign-compare]之间的比较".

Only for the last comparison i get a compiler warning: "comparison between signed and unsigned integer expressions [-Wsign-compare]".

为什么只在最后一种情况下才会发生这种情况?

Why does this only happen in the last case but not in the others?

推荐答案

由于操作数的类型不同,因此发生了一组隐式转换以达到相同的类型.

since the type of operands are different a set of implicit conversions take place to reach a common type.

对于二进制运算符(移位除外),如果提升的操作数 具有不同的类型,另外一组隐式转换是 应用,通常称为算术转换,目的是 产生普通类型(也可以通过std :: common_type类型访问 特质)

For the binary operators (except shifts), if the promoted operands have different types, additional set of implicit conversions is applied, known as usual arithmetic conversions with the goal to produce the common type (also accessible via the std::common_type type trait)

由于整数类型,此处积分转化适用于:

because of integral types here integral conversions is applied to:

  • 如果任何一个操作数具有范围内的枚举类型,则不执行任何转换:另一个操作数和返回类型必须具有相同的
    类型
    • 否则,如果其中一个操作数为long double,则另一个操作数将转换为long double
    • 否则,如果其中一个操作数为double,则另一个操作数将转换为double
    • 否则,如果其中一个操作数为float,则另一个操作数将转换为float
    • 否则,操作数具有整数类型(因为bool,char,char8_t,char16_t,char32_t,wchar_t 和无作用域枚举 在这一点上得到了提升),而整体转化是 来生成通用类型,如下所示:
    • 如果两个操作数都是带符号的,或者都是无符号的,则转换等级较小的操作数将被转换为带有 更大的整数转换排名
    • 否则,如果无符号操作数的转换等级大于或等于有符号操作数的转换等级 操作数,有符号操作数将转换为无符号
      操作数的类型.
    • 否则,如果有符号操作数的类型可以表示无符号操作数的所有值,则将无符号操作数转换为 有符号操作数的类型否则,两个操作数都将转换为 有符号操作数类型的无符号对应物.
  • If either operand has scoped enumeration type, no conversion is performed: the other operand and the return type must have the same
    type
    • Otherwise, if either operand is long double, the other operand is converted to long double
    • Otherwise, if either operand is double, the other operand is converted to double
    • Otherwise, if either operand is float, the other operand is converted to float
    • Otherwise, the operand has integer type (because bool, char, char8_t, char16_t, char32_t, wchar_t, and unscoped enumeration were promoted at this point) and integral conversions are applied to produce the common type, as follows:
    • If both operands are signed or both are unsigned, the operand with lesser conversion rank is converted to the operand with the greater integer conversion rank
    • Otherwise, if the unsigned operand's conversion rank is greater or equal to the conversion rank of the signed operand, the signed operand is converted to the unsigned
      operand's type.
    • Otherwise, if the signed operand's type can represent all values of the unsigned operand, the unsigned operand is converted to the signed operand's type Otherwise, both operands are converted to the unsigned counterpart of the signed operand's type.

相同的算术转换也适用于比较运算符.

The same arithmetic conversions apply to comparison operators too.

可以得出结论,因为rhs都是uint8_t,公共类型将是int,然后由于rhsuint32_t,所以==运算符的公共类型将是uint32_t . 但是由于某种原因,我不知道gcc不会在clang执行时进行最后一次转换.请参阅 godblot +运算符的gcc类型转换. 警告也可能是错误警告,并且转换发生了,就像+运算符一样. 看到如何看到的最后(

from all this one can conclude since the rhs are all uint8_t the common type will be int, and then since the rhs is uint32_t the common type of == operator will be uint32_t. but for some reason that I have no idea gcc don't do the last conversion while clang does it. see the gcc type conversion for + operator in godblot It also could happen that the warning is a false warning and the conversion took place, as it happened for + operator. See how clang sees the last if(cppinsights):

if(foo == static_cast<unsigned int>(static_cast<int>(a) + (static_cast<int> 
(b) * static_cast<int>(c))))

更新:

我找不到这两个编译器生成的程序集之间的差异,因此同意@ M.M,因此,IMO,这是一个gcc错误.

I couldn't find a difference in the assembly generated by the two compilers and would agree with @M.M so, IMO it's a gcc bug.

这篇关于解释整数与促销的比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆