这更像是一个理论问题.我是计算机科学专业的学生,对低级编程非常感兴趣.我喜欢了解引擎盖下的工作原理.我的专业是编译器设计.

无论如何,当我在我的第一个编译器上工作时,我正在发生一些让我感到困惑的事情.

当你用C/C++编写程序时,人们知道的传统事情是,编译器会神奇地将你的C/C++代码转换成该机器的本机代码.

但这里有些东西说不通.如果我针对x86体系 struct 编译我的C/C++程序,似乎相同的程序应该在任何具有相同体系 struct 的计算机上运行.但那不会发生.你需要在OSX、Linux或Windows上重新编译你的代码.(32位VS 64位也需要重新编译.)

我只是想知道为什么会这样?在编译C/C++程序时,我们不是以CPU体系 struct /指令集为目标吗?Mac操作系统和Windows操作系统在很大程度上可以运行在相同的架构上.

(我知道Java和类似的目标是VM或CLR,所以这些不算)

如果我能给出一个最好的答案,我会说C/C++必须编译成特定于操作系统的指令.但我读到的每一条消息都说编译器的目标是机器.所以我很困惑.

推荐答案

在编译C/C++程序时,我们不是以CPU体系 struct /指令集为目标吗?

不,你没有.

我的意思是,是的,您正在为CPU指令集编译.但那不是all个汇编.

想想最简单的"你好,世界!"程序它所做的就是拨打printf,对吗?但是没有"printf"指令集操作码.所以到底发生了什么?

这是C标准库的一部分.它的printf函数对字符串和参数进行一些处理,然后...显示它.这是怎么发生的?它将字符串发送到标准输出.好啊谁来控制?

操作系统.而且也没有"standard out"操作码,所以向standard out发送字符串涉及某种形式的操作系统调用.

操作系统调用也没有跨操作系统标准化.几乎所有的标准库函数都是在C或C++中自己构建的,它将与OS对话,至少要完成它的一些工作.

malloc? 记忆不属于你;它属于操作系统,你可以拥有一些.scanf? 标准输入不属于你;它属于操作系统,你可以从中阅读.等等

您的标准库是通过对操作系统 routine 的调用构建的.这些操作系统 routine 是不可移植的,所以你的标准库实现是不可移植的.所以你的可执行文件中有这些不可移植的调用.

除此之外,不同的操作系统对什么是"可执行文件"有不同的看法.毕竟,可执行文件不仅仅是一堆操作码;你认为所有这些常量和预初始化的static个变量都存储在哪里?不同的操作系统有不同的启动可执行文件的方式,可执行文件的 struct 就是其中的一部分.

C++相关问答推荐

GCC:try 使用—WError或—pedantic using pragmas

从内联程序集调用Rust函数和调用约定

如何解决C中的严格别名?

括号中的堆栈实现错误问题

在C中将通用字符名称转换为UTF-8

有没有可能我不能打印?(C,流程)

如何知道我是否从非阻塞套接字读取所有内容

拥有3x3二维数组并访问数组[1][3]等同于数组[2][0]?

用C宏替换strncMP函数中的参数

在Rust和C之间使用ffi时如何通过 struct 中的[U8;1]成员传递指针

FRIDA-服务器成为端口扫描的目标?

如何在不读取整个字符串的情况下删除UTF8字符串的尾随空格以提高性能?

Valgrind用net_pton()抱怨

我不知道为什么它不能正常工作,我用了get()和fget(),结果是一样的

程序对大输入给出错误答案

OMP并行嵌套循环

浮动目标文件,数据段

Matlab/Octave对conv2函数使用哪种方法?

按字典顺序打印具有给定字符的所有可能字符串

如何在C中以0x格式打印十六进制值