为什么c++标准库与编译器捆绑在一起而不是与操作系统捆绑在一起?

Why is the C++ standard library bundled with the compiler instead of the os?

本文关键字:在一起 操作系统 c++ 编译器 为什么 标准      更新时间:2023-10-16

如果这是一个幼稚的问题,我很抱歉,但有些事情我无法理解。

为什么c++标准库与不同的编译器实现(g++libstdc++clanglibc++)捆绑在一起,而不是与(类unix)操作系统捆绑在一起,就像C标准库一样?考虑到它是C库的超集,为什么不与C库一起维护呢?

根本原因是没有标准的c++ ABI——每个编译器都倾向于有自己的不同于其他编译器的、不兼容的ABI。另一方面,大多数操作系统定义了他们使用的标准C ABI并提供了标准C库,并且该操作系统的所有C编译器都支持该ABI。

操作系统通常不支持语言。它们只支持自己的系统调用。在大多数操作系统中,这种支持是作为C库的一部分提供的,因为C具有最低级别的链接。其他语言和运行时(如c++, python等)在操作系统的系统调用支持库之上构建它们的运行时支持。

C库也是分开维护的:glibc和Windows的msvcr*(不知道Mac上的细节)。它"随操作系统而来"的事实是,所有(大多数)二进制文件都与它相关联,所以没有它什么都不能工作。当然,c++标准库也可以这样说,但没有那么严格。

编译器通常提供库编写者用来促进开发的扩展。当实现一个新特性时,将对库进行调整。有时这些变化正在破裂。在glibc/libstdc++(/libc++?)的情况下,库内部保持向后兼容性(使用版本化符号)。以Windows的CRT为例,C和c++标准库出现了各种不兼容的版本,并与每个编译器版本相耦合。另外:在Visual Studio的情况下,编译器倾向于在不同版本之间破坏ABI,因此"操作系统"将不得不附带所有版本的库。

PS:当然,对于Windows来说,在Windows Update中包含较新的CRT/c++ lib版本可能会更"干净"。其他的选择早在很久以前就做出了,而且大多数一直坚持到现在。

c++库的源代码与GCC源代码捆绑在一起。这是有道理的,因为c++库与c++语言密切相关。它不是操作系统组件。它的某些方面,如内存管理和I/O,确实与操作系统设施接口,但大部分没有。

另一方面,c++库的实际捆绑是操作系统发行版的工作(例如一些GNU/Linux)。

最终,是你的发行版决定了如何打包libstdc++。例如,它可能是一个独立的包(它甚至可能需要出现在几个版本中)。这是因为libstdc++提供了一个共享库,无论是否安装编译器,其他包都需要这个共享库作为依赖项。有些包可能只适用于这个库的特定版本。

"操作系统的一部分"或"编译器的一部分"并没有真正的意义:问题是"哪个包的一部分",这是特定于发行版的,因为当你构建GCC套件时,你的构建脚本可以根据你对如何组织发行版的看法,将临时安装树拆分为任意的包。

假设我们制作了一个"ceeplusplusy"操作系统发行版。c++库可以被认为是操作系统的重要组成部分。也就是说,假设启动操作系统所需的核心应用程序都是用c++重写的,并且都使用库:比如系统守护进程、shell、"getty"等等。然后在早期引导阶段需要c++库。最终,什么是操作系统,什么不是?

在Mac上,你会发现两者都是libc。dylib(标准C库)和libc++。/usr/lib目录下的dylib(标准c++库)。在iOS设备上,你不容易找到它们,但它们都在那里。很明显,它们不是编译器的部分,因为它们对于几乎所有程序的运行都是必不可少的,即使您从未安装任何编译器,它们也会出现。

相关文章: