为什么c++标准库与编译器捆绑在一起而不是与操作系统捆绑在一起?
Why is the C++ standard library bundled with the compiler instead of the os?
如果这是一个幼稚的问题,我很抱歉,但有些事情我无法理解。
为什么c++标准库与不同的编译器实现(g++
的libstdc++
和clang
的libc++
)捆绑在一起,而不是与(类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设备上,你不容易找到它们,但它们都在那里。很明显,它们不是编译器的部分,因为它们对于几乎所有程序的运行都是必不可少的,即使您从未安装任何编译器,它们也会出现。
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 将图形属性与 std::unique_ptr 捆绑在一起
- WideCharToMultiByte在英语操作系统上不转换日语
- 你能在 c++ 中将不同的数字类型加在一起吗?
- 如何将两个字符串加在一起,就好像它们是变量一样?
- 当返回语句时,逗号运算符、大括号初始化列表和 std::unique_ptr 组合在一起
- 为什么push_back和emplace_back结合在一起时,会有不同的行为
- 在浮点精度成为一个问题之前,可以将多少个浮点值加在一起
- 为什么在template函数广播中把两个extensor表达式加在一起不正确
- 实现具有浮点键的类似哈希表的数据结构,其中公差内的值被合并在一起
- 如何在Qt TableView中将列的宽度调整为数据并将最后一部分拉伸在一起
- 编译器如何将链表中的地址字符串在一起?
- 程序在没有操作系统信号的情况下在函数中的特定行挂起
- 在 c++ 中,两个日志行与 log4Cxx 混合在一起
- 如何将两个 jlong 数据类型转换为 jstring,然后将两个字符串连接在一起以便从 JNI 将字符串返回给 jav
- 将许多向量排序在一起
- C++ std:: 并包括它们如何组合在一起?
- 通过字符串迭代并将每个循环中的先前字符组合在一起
- CMake 项目结构:如何正确地将库合并在一起并将它们包含在多个可执行文件中
- 为什么c++标准库与编译器捆绑在一起而不是与操作系统捆绑在一起?