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

dw1jzc5e  于 2022-12-05  发布在  其他
关注(0)|答案(2)|浏览(114)

我通过this的回答得知:
在C20中,计算引起的有符号溢出仍然是未定义的行为,而转换引起的有符号溢出在C20中有明确定义(这是为Pre-C++20定义的实现)。
转换导致有符号溢出的这种变化是因为C20编译器要求使用2的补码。
我的问题是
如果编译器需要使用C
20中的2的补码,那么为什么计算导致的有符号溢出不能像转换导致的有符号溢出一样定义良好?
也就是说,为什么(如何)在计算溢出和转换溢出之间有区别。本质上,为什么这两种溢出被区别对待。

ohtdti5x

ohtdti5x1#

如果非二进制补码支持是唯一的考虑,那么有符号算术溢出可以被定义为具有实现定义的结果,就像转换整数已经被定义一样。有原因为什么它是UB,这些原因没有改变,也没有改变有符号算术溢出的规则。
在任何UB的情况下,其存在基本上有两个主要原因:

  • 可移植性。不同的系统以不同的方式运行,UB允许以最佳方式支持所有系统。在这种情况下,正如Martin Rosenau在评论中提到的,有些系统不会简单地产生“错误”的值。
  • 优化。UB允许编译器假设它不会发生,从而允许基于该假设的优化。Jarod42在注解中给出了一个例子。另一个例子是,通过UB溢出,可以推断出两个正数相加永远不会产生负数,也不会产生小于其中任何一个正数的数字。

相关问题