当前位置: 首页 > 知识库问答 >
问题:

为什么C 20中由于计算导致的签名溢出仍然是未定义的行为

暨承平
2023-03-14

通过这个答案,我知道:

由于计算导致的有符号溢出在C 20中仍然是未定义的行为,而由于转换引起的有符号溢出在C 20中定义得很好(这是为Pre-C 20定义的实现)。

这种由于转换引起的有符号溢出的变化是因为来自C 20编译器的有符号溢出需要使用二进制补码。

我的问题是:

如果编译器需要使用C 20中的2的补码,那么为什么由于计算定义良好而导致的有符号溢出就像由于转换而导致的有符号溢出一样呢?

也就是为什么(如何)计算导致的溢出和转换导致的溢出有区别。本质上,为什么这两种溢出被区别对待。

共有1个答案

别永年
2023-03-14

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

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

  • 便携性。不同的系统以不同的方式运行,UB允许以最佳方式支持所有系统。在这种情况下,正如Martin Rosenau在评论中提到的,有些系统不会简单地产生“错误”的值
  • 优化。UB允许编译器假设它不会发生,从而允许基于该假设进行优化。Jarod42在注释中显示了一个示例。另一个例子是,有了UB溢出,就可以推断出两个正数相加永远不会产生负数,也不会产生小于正数的数字
 类似资料:
  • 众所周知,有符号整数溢出是一种未定义的行为。但是在C 11文档中有一些有趣的东西: 带符号整数类型,宽度分别为8、16、32和64位,不带填充位,并使用2的补码表示负值(仅在实现直接支持该类型时提供) 参见链接 我的问题是:既然标准明确规定,、、和负数是2的补码,那么这些类型的溢出仍然是一种未定义的行为吗? 编辑我检查了C 11和C11标准,以下是我的发现: C 11,§18.4.1: 标题定义了

  • 为什么我在下面的代码段中的X轴上有一个溢出? 在我的网格容器上应用时,就会产生溢出。 null null https://codepen.io/anon/pen/wdjexz?editors=1100

  • 问题是当我将页面收缩到某个点时, 元素的顶部溢出,奇怪的是底部没有溢出。说清楚一点,我不想让这两个都溢出来。 这里有一个指向它的JSFiddle链接:https://jsfidle.net/maep468x/1 您将看到,当您运行它并将结果窗口缩小到大约350px时, 元素开始溢出。 我已经尝试从.main-content规则中删除我的line-height和font-size属性,但它仍然溢出。

  • 我有一个使用Libgdx游戏引擎的Android游戏。我有一个Android活动(mAndroidLauncher),它扩展了Libgdx的AndroidApplication类。有一种方法可以创建Android警报对话框: 我在Google Play开发人员控制台中遇到了如下问题: 这是我的应用程序中唯一使用AlertDialog的地方,这就是为什么我确信这是导致崩溃的方法。为什么RUNNUIT

  • 未定义行为的一个例子是在flow上的整数行为 有没有一个历史的或者(甚至更好!)造成这种差异的技术原因是什么?