解释整数与促销的比较

Ral*_*alf 13 c++ integer-promotion

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

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

为什么这仅在最后一种情况下发生而在其他情况下不发生?

Obl*_*ica 5

由于操作数的类型不同,需要进行一组隐式转换以达到通用类型。

对于二元运算符(移位除外),如果提升的操作数具有不同的类型,则应用额外的一组隐式转换,称为通常的算术转换,其目标是生成公共类型(也可通过 std::common_type 类型特征访问)

由于这里的整数类型,整数转换适用于:

  • 如果任一操作数具有范围枚举类型,则不执行转换:另一个操作数和返回类型必须具有相同的
    类型
    • 否则,如果任一操作数为 long double,则另一个操作数将转换为 long double
    • 否则,如果任一操作数为 double,则将另一个操作数转换为 double
    • 否则,如果任一操作数为浮点数,则另一个操作数将转换为浮点数
    • 否则,操作数具有整数类型(因为此时提升了 bool、char、char8_t、char16_t、char32_t、wchar_t和无作用域枚举)并应用整数转换来生成公共类型,如下所示:
    • 如果两个操作数都是有符号的或都是无符号的,则转换等级较小的操作数将转换为整数转换等级较大的操作数
    • 否则,如果无符号操作数的转换等级大于或等于有符号操作数的转换等级,则有符号操作数被转换为无符号
      操作数的类型。
    • 否则,如果有符号操作数的类型可以表示无符号操作数的所有值,则将无符号操作数转换为有符号操作数的类型。否则,两个操作数都将转换为有符号操作数类型的无符号对应项。

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

从这一切可以得出结论,因为rhs所有uint8_t的公共类型都是 int,然后因为rhs是运算符uint32_t的公共类型==将是uint32_t。但出于某种原因,我不知道gcc在 clang 进行时不要进行最后一次转换。参见Godblot 中operator的gcc类型转换 也可能发生警告是错误警告并且转换发生了,就像operator发生的那样。看看如何看到最后(cppinsights):++clangif

if(foo == static_cast<unsigned int>(static_cast<int>(a) + (static_cast<int> 
(b) * static_cast<int>(c))))
Run Code Online (Sandbox Code Playgroud)

更新:

我在两个编译器生成的程序集中找不到差异,并且同意@MM 所以,IMO 这是一个gcc错误。