为什么C++下溢/溢出行为被认为是未定义的?

use*_*166 8 c++

我知道整数下溢和溢出是未定义的.

但是,鉴于C++最终编译为汇编,实际定义的行为是不是?

按位表示保持不变,整数格式保持不变0111..11总是会翻转到1000..00,同为下溢,那么为什么不考虑定义的行为?

关于汇编汇编,我是从我们在学校教授的基本程序集中得出的,但代码块给出了

int x = INT_MAX;
int y = x+1;
Run Code Online (Sandbox Code Playgroud)

编译成

00401326    movl   $0x7fffffff,0x8(%esp)
0040132E    mov    0x8(%esp),%eax
00401332    inc    %eax
00401333    mov    %eax,0xc(%esp)
Run Code Online (Sandbox Code Playgroud)

现在,无论x的值如何,总是会有inc或add指令?那么,未定义的行为出现在哪里?

The*_*ant 6

但是,鉴于C++最终编译为汇编,实际定义的行为是不是?

不,因为编译器决定它发出什么样的程序集.如果编译器希望,它可以生成如果遇到未定义的行为则擦除硬盘的程序集.

(实际上,"C++最终编译成汇编"可能不是真的.例如,存在C++解释器 - 标准没有规定C++应该如何编译/编译.

标准的创建者决定不定义的原因之一是 - 几乎总是 - 优化的机会.如果有符号溢出是UB,那么编译器可以假设它x + 1 > x始终为true并生成依赖于此前提条件的更简单/更短/更快的代码.


Bar*_*icz 5

在C++标准中,有符号整数的溢出是未定义的,正是因为不同的编译器,汇编器和平台可能会对它们进行不同的解释.

当您知道要运行的平台时,您可以推断出程序的行为,但是如果没有这些知识,就无法预测它的行为方式.

按位表示保持不变,整数格式保持不变

这根本不是真的.

  • @ user87166 http://en.wikipedia.org/wiki/Signed_number_representations#Comparison_table (4认同)
  • @ user87166当编译器优化它时,因为它总是UB. (2认同)