gpt4 book ai didi

c++ - 在执行过程中如何用C++代码在计算机中找到Iostream文件

转载 作者:行者123 更新时间:2023-11-30 02:45:58 28 4
gpt4 key购买 nike

我想知道在执行过程中的C++代码中如何创建iostream文件。我们在C++程序中编写#include,我知道#include是预处理程序指令
加载文件,是一个文件名,但我不知道该文件的位置。
我在想一些问题...

  • 我们正在使用的编译器中是否存在标准库?
  • 该文件存在于标准库中还是在我们的计算机中?
  • 我们可以给目录路径通过c++代码定位文件吗?
  • 最佳答案

    您似乎对C++的编译和执行模型感到困惑。通常不解释C++(尽管可以解释),但是在编译阶段会生成一个本机二进制文件,然后执行该二进制文件。因此,我们绕道而行。

    为了从少数文本文件转到正在执行的程序,有几个步骤:

  • 编译
  • 链接
  • 加载
  • 执行正确

  • 我将仅描述传统编译器的功能(例如gcc或clang),可能的变化将在以后说明。

    编译

    在编译期间,每个源文件(通常是 .cpp.cxx,尽管编译器可能不太在意)都经过处理以生成目标文件(在Linux上通常为 .o):
  • 源文件已经过预处理:这意味着解析#include(将文件包含/复制/粘贴到当前文件中),浏览#if#else以删除不需要的源并扩展宏。
  • preprocessed file被馈送到编译器,编译器将为每个函数,static或全局变量等生成本地代码。格式取决于一般
  • 中的目标系统。
  • 编译器输出object file(通常是二进制格式)

  • 链接

    在此阶段,将多个目标文件组装在一起成为一个库或可执行文件。对于静态库或静态链接的可执行文件,其依赖的库也将组装在生成的文件中。

    传统上,链接器作业相对简单:它只是连接所有目标文件,这些文件已经包含目标计算机可以执行的二进制格式。但是实际上它通常会做更多的事情:在C和C++中,内联函数在目标文件之间重复,因此链接程序仅需要保留其中一个定义。

    至此,程序已经“编译”了,我们进入了编译器的境界。

    正在加载

    当您要求执行程序时,操作系统会将其代码加载到内存中(这要感谢加载器)并执行。

    对于静态链接的可执行文件,这很容易:这只是需要加载的一大块代码。对于动态链接的可执行文件,它意味着找到依赖关系并“解析符号”,下面将对此进行描述:
  • 首先,您的动态链接的可执行文件和库有一节描述了它们依赖的其他库。它们仅具有库的名称,而没有其确切位置,因此加载器将在路径列表(例如Linux中的LD_LIBRARY_PATH)中搜索该库,并实际加载它们。
  • 加载库时,加载器将执行替换操作。您的可执行文件中的占位符说“这里应该是printf函数的地址”,加载程序将用实际地址替换该占位符。

  • 正确加载所有内容后,应解析所有符号。如果缺少某些符号,即在当前库或其任何依赖项中都找不到它们的代码,则通常会收到错误(立即或仅在使用延迟加载时才真正需要该符号时)。

    执行

    现在执行代码(二进制格式的汇编器指令)。在C++中,这始于构建全局对象和 static对象(在文件范围内,而不是函数静态的),然后继续调用 main函数。

    注意事项:这是一个简化的 View ,如今链接时间优化意味着链接器将做越来越多的事情,加载器实际上也可以执行优化,并且如上所述,使用延迟加载,可以在执行开始后调用加载器...仍然,您必须从某个地方开始,不是吗?

    那么,关于您的问题意味着什么?

    源代码中的 #include <iostream>是预处理程序指令。因此,它在编译阶段的早期就已完全解决,并且仅取决于找到合适的头文件(实际上还不需要库代码)。注意:将允许编译器不存在头文件,而只是神奇地注入(inject)必要的代码,就好像头文件存在一样,因为这是标准库头(因此很特殊)。对于常规 header (您的),将调用预处理器。

    然后,在链接时:
  • (如果您使用静态链接),链接器将搜索标准库并将其包含在生成
  • 的可执行文件中
  • (如果您使用动态链接),链接器将注意它取决于标准库文件(例如libc++.so),并且生成的代码缺少printf的实现(例如)

  • 然后,在加载时:
  • (如果您使用了动态链接),则加载程序将搜索标准库并加载其代码

  • 然后,在执行时,最终执行代码(您及其依赖性)。

    我想到了几个标准库实现:
  • MSVC附带了Dirkumware的修改版本
  • gcc随附libstdc++(取决于libc)
  • clang附带libc++(取决于libc),但可以改用libstdc++(带有编译器标志)

  • 当然,您可以提供其他...可能...虽然设置起来可能并不容易。

    最终使用哪个取决于您使用的编译器选项。默认情况下,最常见的编译器附带其自己的实现,并且无需您的任何干预即可使用它。

    最后是的,您确实可以在 #include指令中指定路径。例如,使用 boost:
    #include <boost/optional.hpp>
    #include <boost/algorithm/string/trim.hpp>

    您甚至可以使用相对路径:
    #include <../myotherproject/x.hpp>

    尽管某些人认为此格式不正确(因为一旦您重新组织文件就会中断)。

    重要的是预处理器将浏览目录列表,并为每个目录附加 /和您指定的路径。如果这创建了一个现有文件的路径,它将选择它,否则它将继续到下一个目录...直到用完(并抱怨)。

    关于c++ - 在执行过程中如何用C++代码在计算机中找到Iostream文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24009466/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com