C++ 标准库在幕后是如何工作的?

How does the C++ standard library work behind the scenes?

这两天这个问题一直困扰着我。我想知道标准库在功能方面是如何工作的。我无法在任何地方找到答案,即使通过检查 LLVM 编译器提供的 source code,对于像我这样的初学者来说,这是一段非常复杂的代码。

我在这里基本上想了解的是 C++ 标准库是如何工作的。例如,让我们以 fstream 头文件为例,它包含一堆有助于写入和读取文件的函数。

它是如何工作的?它使用 OS 特定的 API (因为库是跨平台的),还是什么?而且,如果标准库可以做到这一点,难道我不应该在不调用标准 fstream 文件的情况下也能弄乱一些文件吗(根据我的经验,我不能这样做)?

如果我的问题不清楚,我深表歉意,因为我不是以英语为母语的人:请随时修改此文本以使其更清楚。

编译器只是一个创建可执行文件或库的程序。您可以使用编译器默认库来赢得时间或编写您自己的库。默认库与 os 通信以进行文件操作或内存分配,并提供一个简单的标准 类 以允许开发人员仅编写一个代码,该代码可在编译器和库支持的所有目标平台上运行。如果您想自己编写,则必须为所有目标编写每个函数 os.

从某种意义上说,标准库是跨平台的,它的接口不会在平台之间改变,但它的实现会——或者实际上——如果你只使用 C++ 及其标准库,你可以编写相同的代码Linux / Windows / MacOS / Android / Whatever 并且如果您找到支持您使用的语言功能的平台之一的 C++ 编译器,您将能够编译您的该平台的代码,无需重写任何内容。

因此,尽管您可以独立于您正在编写的平台使用 std::vectorstd::fstream 或库中的任何其他功能,并期望函数定义、类型名称等看起来同样,您不能指望使用 Windows 为 PC 编译的可执行文件 10 到 运行 在 phone 和 Android 上。您甚至不能指望在同一台 PC 上使用不同的系统将相同的可执行文件 运行 - 这就是我所说的 "the implementation is different"

造成这种差异的主要原因有两个:

  1. 具有不同架构(例如 x86-64 和 ARM)的处理器使用不同的指令集,因此 C++ 源代码需要编译为完全不同的机器代码才能 运行 正确
  2. 具有相同体系结构处理器但具有不同操作系统的计算机具有不同的动态分配内存、创建文件、创建流、写入控制台、创建和调度线程等的方式 - 这是系统功能的一部分你通过标准库使用的

如果你真的想要,你可以使用 HeapAlloc() instead of operator new() or CreateThread() 而不是 stdlib 的 std::thread 但这会迫使你每次都重写你的程序,而不是 [=48] =] 并使用目标平台的编译器重新编译它(并通过代理学习它的 API)。标准库通过抽象掉那些系统调用,使您免于麻烦。

特别是 fstreamhere 是当今大多数 PC 内部使用的

Does it use the OS specific API (since the library is cross platform), or what?

在某些时候,使用 OS 特定的 API。 fstream 实现不一定直接调用 OS 函数。它可能使用其他 类,调用从 C 等继承的函数,但最终调用链将导致 OS 调用。 (是的,对于中级程序员来说,细节往往过于复杂,无法理解。因此,作为一个自称初学者的人,您的发现并不令人惊讶。)

该库是跨平台的,因为在您这一端(C++ 程序员),无论平台如何,接口都是相同的。然而,它并不是每个平台上的同一个库。每个平台都有自己的库,在 C++ 端公开相同的接口,但使用不同的 OS 调用。 (事实上​​ ,同一个平台可能有多个标准库,因为库实现是由您的工具链提供的,而不是由标准委员会提供的。)

And, if the standard library can do it, aren't I supposed to be able to mess with some files as well without calling the standard fstream file (which to my experience I can't do)?

是的,你可以。显然,您还不能做到,但通过一些练习和指导,您应该能够做到。标准库中的所有内容都可以用您自己的代码重新创建。标准库(以及大多数库,就此而言)的要点是节省您的时间,而不是启用一些原本不可用的东西。例如,您不必为编写的每个程序都实现一个文件流;它在标准库中,因此您可以专注于项目中更有趣的方面。

基本上,fstreamiostreamprintf 基于核函数 write() 工作。当你的代码调用 printf(我们以 printf 为例)时,它最终会调用 write() 让内核处理 IO 的东西。之后,write() returns 和 printf returns 以及您的代码继续。

所以如果你真的想知道printf内部是如何工作的,你必须阅读内核的源代码。

但你现在不应该这样做。

对于初学者,在对计算机没有基本认知的情况下,不要尝试深入。计算机是一个项目,就像建筑物一样。所以正确的学习方法是一层一层地学习。首先,学习如何用砖头和水泥盖房子,这是你现在应该做的。你不应该做的是,你正在学习如何建造建筑物,这是你第一次尝试使用砖,然后你对如何生产砖感兴趣并开始专注于砖,这是错误的方式学习 IT。

如果你正在学习C/C++,那就学吧。记住,一级一级地学习。现在,知道如何使用 printf 就足够了。