【问题标题】:uint8_t and int8_t conversionuint8_t 和 int8_t 转换
【发布时间】:2022-11-12 17:32:45
【问题描述】:

考虑以下程序:

using namespace std;

int main()
{
    uint8_t b = 150;
    int8_t a = -10;
    
    if (a>b){
        cout << "greater" << endl;
    }
    else{
        cout << "less" << endl; 
    }

    return 0;
}

Online C++14 Compiler 中它打印less。我在 Compiler Explorer 和 x86-64 gcc 12.2 中得到的结果相同

根据documentation

否则,操作数为整数类型(因为此时提升了 bool、char、char8_t、(C++20 起)char16_t、char32_t、(C++11 起)wchar_t 和无作用域枚举)并且整数转换应用于产生普通类型,如下:

  1. 如果两个操作数都带符号或都无符号,则转换等级较低的操作数将转换为整数转换等级较高的操作数。
  2. 否则,如果无符号操作数的转换等级大于或等于有符号操作数的转换等级,则将有符号操作数转换为无符号操作数的类型。
  3. 否则,如果有符号操作数的类型可以表示无符号操作数的所有值,则将无符号操作数转换为有符号操作数的类型。
  4. 否则,两个操作数都将转换为有符号操作数类型的无符号对应项。

    在带有 x86-64 gcc 12.2 的 Compiler Explorer 中,我编译它并得到以下结果:

    .LC0:
            .string "greater"
    .LC1:
            .string "less"
    main:
            push    rbp
            mov     rbp, rsp
            sub     rsp, 16
            mov     BYTE PTR [rbp-1], -106
            mov     BYTE PTR [rbp-2], -10
            movsx   edx, BYTE PTR [rbp-2]
            movzx   eax, BYTE PTR [rbp-1]
            cmp     edx, eax
            jle     .L2
            mov     esi, OFFSET FLAT:.LC0
            mov     edi, OFFSET FLAT:_ZSt4cout
            call    std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)
            mov     esi, OFFSET FLAT:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
            mov     rdi, rax
            call    std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))
            jmp     .L3
    ...
    

    所以,根据

    mov     BYTE PTR [rbp-1], -106
    mov     BYTE PTR [rbp-2], -10
    
    

    uint8_t b 被转换为 int8_t 并被赋值为 -106,这似乎是真的,因为它属于文档的第 3 点:

    否则,如果有符号操作数的类型可以表示无符号操作数的所有值,则将无符号操作数转换为有符号操作数的类型。

    如果我正确理解文档和汇编代码,则比较

    (a>b) //-10 > -106 
    

    应该返回真。但显然,它返回 false,因为我得到了 else 分支的输出。

    所以我的问题是:为什么 (a&gt;b) 在此示例中返回 false?

【问题讨论】:

    标签: c++ type-conversion


    【解决方案1】:

    您忘记了积分促销。来自https://en.cppreference.com/w/cpp/language/operator_arithmetic

    如果传递给算术运算符的操作数是整数或无作用域枚举类型,则在任何其他操作之前(但在左值到右值转换之后,如果适用),操作数会经历整数提升。

    来自https://en.cppreference.com/w/cpp/language/implicit_conversion#Integral_promotion

    小整数类型(如 char)的纯右值可以转换为较大整数类型(如 int)的纯右值

    ab都先提升为int,然后进行比较。作为int

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      • 2015-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      相关资源
      最近更新 更多