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

C99标准中哪里说有符号整数溢出是未定义的行为?

袁秦迟
2023-03-14

C99标准中哪里说有符号整数溢出是未定义的行为?

我看到关于无符号整数溢出的评论定义得很好(看看为什么定义了无符号整数溢出行为,但没有定义有符号整数溢出?)在第6.2.5节中:

涉及无符号操作数的计算永远不会溢出,因为不能由结果无符号整数类型表示的结果将被减少为比结果类型可以表示的最大值大一的数的模。

但是我在附录J中查看了未定义的行为,我只在列表中看到了这些类似的项目:

具有有符号提升类型的表达式将左移位,并且表达式的值为负值,或者移位的结果将无法在提升类型中表示

整数算术或转换函数的结果值无法表示

(注意,这指的是“整数算术函数”,而不是整数算术本身。)

共有1个答案

宋朝
2023-03-14

我没有C99的副本,但在C11标准中,该文本出现在第6.5节第5段:

如果在表达式求值过程中出现异常情况(即,如果结果未在数学上定义或不在其类型的可表示值范围内),则行为未定义。

这似乎是对任何溢出的一种通吃;然后,关于无符号整数的文本成为6.5¨5以上的特例。

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

  • 众所周知,有符号整数溢出是一种未定义的行为。但是在C 11文档中有一些有趣的东西: 带符号整数类型,宽度分别为8、16、32和64位,不带填充位,并使用2的补码表示负值(仅在实现直接支持该类型时提供) 参见链接 我的问题是:既然标准明确规定,、、和负数是2的补码,那么这些类型的溢出仍然是一种未定义的行为吗? 编辑我检查了C 11和C11标准,以下是我的发现: C 11,§18.4.1: 标题定义了

  • 最近,有符号整数溢出在C和C中没有正式定义,这引起了很多关注。然而,给定的实现可能会选择定义它;在C语言中,实现可以设置

  • 这是一个例子来说明我的问题,其中涉及一些更复杂的代码,我不能在这里张贴。 这个程序在我的平台上包含未定义的行为,因为会在第三个循环上溢出。 这会使整个程序有未定义的行为,还是只有在溢出真正发生之后?编译器可能会发现会溢出,这样它就可以声明整个循环未定义,并且不用费心运行printfs,即使它们都发生在溢出之前? (标记的C和C虽然不同,但我对这两种语言的答案感兴趣,如果它们不同的话。)

  • Rust在调试和发布模式下处理有符号整数溢出的方式不同。当它发生时,Rust在调试模式下会恐慌,而在发布模式下会默默地执行两个补码的包装。 据我所知,C/C将有符号整数溢出视为未定义的行为,部分原因是: 在C标准化的时候,表示有符号整数的不同底层架构,例如补码,可能仍在某个地方使用。编译器不能假设硬件中如何处理溢出。 后来的编译器因此做出假设,例如两个正整数的总和也必须是正的,以生成优化的机器代码

  • 我快速浏览了C 03标准,但仍然无法判断这种行为是否有保证: 结果是: VC在32位窗口中给出<code>0xffffffff。但我的假设是,转换可以通过两种方式进行: 1) 8位有符号字符-1首先直接转换为8位无符号值,该值为二进制11111111或十进制255,然后扩展为32位无符号整数,给出255(0xff)。 2)8位有符号字符-1被有符号扩展到32位有符号int,给出0xffffffff