C++:比较不同大小的整数会导致 UB 吗?
C++: Does Comparing different sized integers cause UB?
所以这可能是一个非常简单的问题,如果它不是关于 C++,我会继续检查它是否在我的计算机上工作,但不幸的是,在 C++ 中,事情通常倾向于在几个系统上工作同时仍然是 UB,因此不能在其他系统上工作。
考虑以下代码片段:
unsigned long long int a = std::numeric_limits< unsigned long long int >::max();
unsigned int b = 12;
bool test = a > b;
我的问题是:我们能否将不同大小的整数相互比较,而不使用例如将较小的类型显式转换为较大的类型? static_cast
没有 运行 进入未定义行为 (UB)?
总的来说,我可以想象出三种结果:
- 较小的类型在转换前被隐式转换为较大的类型(通过真正的转换或通过一些能够“假装”它已被转换的巧妙方法)
- 较大的类型在比较前被截断为较小的类型
- 这未定义,需要添加显式转换才能达到定义的行为
这是安全的。 C++ 有所谓的 Usual arithmetic conversions,它们处理如何隐式转换传递给内置二元运算符的对象。
在这种情况下,会发生整数提升,b
会为您转换为 unsigned long long int
,然后计算 operator >
。
这不是未定义的行为。 常用算术转换 涵盖了这些内容,详见 C++17 standard:
的第 8p11.5 节
The integral promotions (7.6) shall be performed on both operands.
Then the following rules shall be applied to the promoted operands:
- (11.5.1) If both operands have the same type, no further conversion is needed.
- (11.5.2) Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser
integer conversion rank shall be converted to the type of the operand
with greater rank.
- (11.5.3) Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other
operand, the operand with signed integer type shall be converted to
the type of the operand with unsigned integer type.
- (11.5.4)Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with
unsigned integer type, the operand with unsigned integer type shall be
converted to the type of the operand with signed integer type.
- (11.5.5)Otherwise, both operands shall be converted to the unsigned integer type corresponding to the type of the operand with signed
integer type.
粗体段落适用于此处。由于这两种类型都是无符号的,较小的类型被转换为较大的类型,因为格式可以包含后者可以包含的值的子集。
所以这可能是一个非常简单的问题,如果它不是关于 C++,我会继续检查它是否在我的计算机上工作,但不幸的是,在 C++ 中,事情通常倾向于在几个系统上工作同时仍然是 UB,因此不能在其他系统上工作。
考虑以下代码片段:
unsigned long long int a = std::numeric_limits< unsigned long long int >::max();
unsigned int b = 12;
bool test = a > b;
我的问题是:我们能否将不同大小的整数相互比较,而不使用例如将较小的类型显式转换为较大的类型? static_cast
没有 运行 进入未定义行为 (UB)?
总的来说,我可以想象出三种结果:
- 较小的类型在转换前被隐式转换为较大的类型(通过真正的转换或通过一些能够“假装”它已被转换的巧妙方法)
- 较大的类型在比较前被截断为较小的类型
- 这未定义,需要添加显式转换才能达到定义的行为
这是安全的。 C++ 有所谓的 Usual arithmetic conversions,它们处理如何隐式转换传递给内置二元运算符的对象。
在这种情况下,会发生整数提升,b
会为您转换为 unsigned long long int
,然后计算 operator >
。
这不是未定义的行为。 常用算术转换 涵盖了这些内容,详见 C++17 standard:
的第 8p11.5 节The integral promotions (7.6) shall be performed on both operands. Then the following rules shall be applied to the promoted operands:
- (11.5.1) If both operands have the same type, no further conversion is needed.
- (11.5.2) Otherwise, if both operands have signed integer types or both have unsigned integer types, the operand with the type of lesser integer conversion rank shall be converted to the type of the operand with greater rank.
- (11.5.3) Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type.
- (11.5.4)Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, the operand with unsigned integer type shall be converted to the type of the operand with signed integer type.
- (11.5.5)Otherwise, both operands shall be converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
粗体段落适用于此处。由于这两种类型都是无符号的,较小的类型被转换为较大的类型,因为格式可以包含后者可以包含的值的子集。