为什么 C++20 中由于计算而导致的有符号溢出仍然是未定义的行为

问题描述 投票:0回答:1

我是通过这个回答才知道的:

由于计算导致的有符号溢出在 C++20 中仍然是未定义行为,而由于转换导致的有符号溢出在 C++20 中得到了很好的定义(对于 C++20 之前的版本是实现定义) .

由于转换导致的有符号溢出的变化是因为 C++20 编译器要求使用 2 的补码。

我的问题是

如果编译器需要使用 C++20 中的 2 的补码,那么为什么不会像由于转换导致的有符号溢出那样因计算而导致的有符号溢出?

也就是说,计算溢出和转换溢出之间为什么(如何)存在差异。从本质上讲,为什么这两种溢出的处理方式不同。

c++ c++20 undefined-behavior integer-overflow signed
1个回答
9
投票

如果非补码支持是唯一的问题,那么有符号算术溢出可以被定义为具有实现定义的结果,就像定义转换整数一样。为什么是 UB 是有原因的,这些原因没有改变,有符号算术溢出的规则也没有改变。

对于任何 UB,其存在本质上有两个主要原因:

  • 便携性。不同的系统有不同的行为方式,UB 允许以最佳方式支持所有系统。在这种情况下,马丁·罗西瑙 (Martin Rosenau) 在评论中提到,有些系统不会简单地产生“错误”的值。
  • 优化。 UB 允许编译器假设它不会发生,从而允许基于该假设进行优化。 Jarod42 在 comment 中展示了一个示例。另一个例子是,通过 UB 溢出,可以推断出两个正数相加永远不会产生负数,也不会产生小于任何一个正数的数字。
© www.soinside.com 2019 - 2024. All rights reserved.