未定义的行为是否适用于asm代码?

Elo*_*off 14 c c++ assembly undefined-behavior language-lawyer

假设您知道您的软件只能运行在两个补码机器上,其中已经很好地定义了带符号的溢出行为.签名溢出仍然是C和C++中未定义的行为,编译器可以用"ret"替换你的整个程序,开始核战争,格式化你的驱动器,或让恶魔飞出你的鼻子.

假设您已在内联asm中签名溢出,您的程序是否仍然调用UB?

如果是,那么单独编译和链接汇编程序呢?

小智 8

"未定义的行为"是指C和.C++标准没有定义程序的行为.如果您的程序包含内联汇编,那么很明显它的行为通常不会被C或C++标准描述.其他一些标准甚至可能定义行为,但这仍然不代表C或C++标准上下文中的"定义行为".

也就是说,C标准确实需要支持扩展的文档.如果程序的行为可以从您的实现文档中推断出来,并且您的实现使您的程序行为不同,那么您的实现将无法符合标准:

4.一致性

8实现应附带一个文档,该文档定义所有实现定义的和特定于语言环境的特征以及所有扩展.

对于C++,此要求已被削弱:

1.4实施合规[intro.compliance]

9每个实现都应包括标识其不支持的所有条件支持的构造的文档,并定义所有特定于语言环境的特征.

1.9程序执行[intro.execution]

2抽象机的某些方面和操作在本国际标准中描述为实施定义[...]每个实施应包括描述其在这些方面的特征和行为的文件.[...]

我无法找到要记录扩展的要求,如果记录在案,则需要正确记录.这表明在C++中,即使你的实现将程序的行为定义为扩展,如果事实证明文档是错误的,那就太糟糕了.

对于C++半标准asm语句(如评论中所述," asm声明是有条件支持的;其含义是实现定义的."),如果您的实现支持它,则需要记录,但当然这是常见的做法.实现以不同于C++标准暗示的方式支持内联汇编,因此这不会给你额外的帮助.