c - 负数右移不仅是未定义的,而且在clang中从一对多映射
问题描述
当我编译这个 C 代码并在我的机器上运行它十几次时,我每次都得到一个不同的 9 位负数。另一台机器上的另一个 clang 编译器产生 10 位不同的正整数。我期待一个奇怪的值,因为负数右移是未定义的,但令我惊讶的是该值不是一个唯一的数字。相反,我得到了具有相同输入的多个值。为什么这不是数学函数?
#include <stdio.h>
int main(void) {
printf("%d", 1 >> -1);
return 0;
}
解决方案
因为没有定义行为,编译器(至少在 Clang 的情况下,见下文)选择不在参数将传递给的寄存器中放置任何内容printf
。这导致寄存器具有准备 C 环境和调用的启动代码留下的任何值main
。这恰好是启动期间使用的某个地址,它是由地址空间布局随机化随机化的,用于阻止对软件的攻击。
对 clang 生成的程序集的检查确认没有任何值被放置在寄存器 %esi 中,该值将用于此参数(使用 Apple LLVM 10.0.0 和 clang-1000.11.45.5,为其在 macOS 10.14.3 中的默认目标构建只有开关-O3
)。
当然,其他编译器的行为可能会有所不同,因为 C 标准没有定义该行为;这仅解释了 OP 在有限情况下报告的观察结果。
推荐阅读
- java - 使用 HTMLUNIT 从标签之间的 HTML 页面中提取数据
- pug - 从快速路线呈现为视图时,mdbootsrap 未显示
- java - ArrayList 抛出 java.lang.ClassCastException
- angularjs - 一个应用程序可以使用 3 个端口吗?
- css - css 加载器的模块解析失败错误
- python-3.x - FileNotFoundError: [WinError 3] 系统找不到指定的路径:
- database - Wordpress 数据库建立数据库连接时出错
- java - 如何实现大量调用oracle DB操作
- java - 为什么我们要像这样打印变量值?
- jquery - 当用户错误填写表单时,如何写入 Bootstrap div 警报?