这是标准算术转换的简单展示:
// Example program
#include <iostream>
using namespace std;
int main()
{
unsigned long a = 0;
int b = 1;
long long c = -1;
cout << (c < a*b) << endl;
}
godbolt 返回 0,cpp.sh 返回 1。
标准(https://en.cppreference.com/w/cpp/language/usual_arithmetic_conversions)说:
第四阶段...
- 如果U的整数转换等级大于或等于S的整数转换等级,则C为U。
- 否则,如果S可以代表U的所有值,则C就是S。
- 否则C就是S对应的无符号整数类型。
哪个编译器是错误以及为什么?
结果取决于 sizeof( unsigned long ) 是否等于 sizeof( long long )。即 long long 类型是否可以包含 unsigned long 类型的所有正值。
如果它不能包含 unsigned long 类型的值,那么在此表达式中
(c < a*b)
常见类型将是 unsigned long long,因此表达式会产生 false 值,因为 -1 会转换为非常大的正值。
否则,如果表达式的通用类型为 long long,因为如上所述,sizeof( insigned long ) 小于 sizeof( long long ) 并且 long long 类型可以包含 unsigned long 类型的所有正值,则表达式将产生值 true .