【发布时间】: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 中得到的结果相同
否则,操作数为整数类型(因为此时提升了 bool、char、char8_t、(C++20 起)char16_t、char32_t、(C++11 起)wchar_t 和无作用域枚举)并且整数转换应用于产生普通类型,如下:
- 如果两个操作数都带符号或都无符号,则转换等级较低的操作数将转换为整数转换等级较高的操作数。
- 否则,如果无符号操作数的转换等级大于或等于有符号操作数的转换等级,则将有符号操作数转换为无符号操作数的类型。
- 否则,如果有符号操作数的类型可以表示无符号操作数的所有值,则将无符号操作数转换为有符号操作数的类型。
- 否则,两个操作数都将转换为有符号操作数类型的无符号对应项。
在带有 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>b)在此示例中返回 false?
【问题讨论】:
标签: c++ type-conversion