C++ 典型的C++;编译器句柄?

C++ 典型的C++;编译器句柄?,c++,compiler-construction,linker,machine-translation,C++,Compiler Construction,Linker,Machine Translation,在研究了一些编译器及其工作原理后,我了解到这个过程通常分为4个步骤:预处理器、编译器、汇编程序和链接器。我设想这些步骤的方式是每一步都是它自己的独立程序;预处理程序、编译程序、汇编程序和链接程序。但是,您了解到,有时创建汇编代码和生成对象文件的过程都由编译器程序处理,有时则不是。这似乎在很大程度上取决于所使用的上下文和编程语言。我的问题是,如何将C++源代码翻译成机器代码的典型翻译过程?p> 预处理器是独立于编译器的程序吗?或者这个过程通常是编译程序的一部分 编译器通常负责什么?生成装配代码,然

在研究了一些编译器及其工作原理后,我了解到这个过程通常分为4个步骤:预处理器、编译器、汇编程序和链接器。我设想这些步骤的方式是每一步都是它自己的独立程序;预处理程序、编译程序、汇编程序和链接程序。但是,您了解到,有时创建汇编代码和生成对象文件的过程都由编译器程序处理,有时则不是。这似乎在很大程度上取决于所使用的上下文和编程语言。我的问题是,如何将C++源代码翻译成机器代码的典型翻译过程?p>
  • 预处理器是独立于编译器的程序吗?或者这个过程通常是编译程序的一部分
  • 编译器通常负责什么?生成装配代码,然后转换为机器代码
  • 链接器是否是编译器完成后运行的单独程序

  • 旁注:我的问题与其他C++编译器线程不同,因为我不仅询问编译器是如何工作的,而且如果某些其他进程,例如链接,是有自己的可执行程序,或者它们通常被编译成编译器程序。p> 所有现代编译器(至少是gcc和clang,但我怀疑其他编译器有很大不同)都将预处理和编译器作为一个可执行文件。这主要是因为编译器希望能够生成良好的错误消息[指向正确的行和列,当涉及到宏时,可以说“从宏FOO(x)”调用],并且当编译器有实际的源代码可查看时,理解“我们所处的文件”比预处理代码更容易

    链接器通常是一个单独的程序,汇编程序只用于内联汇编代码[通常作为编译器的一个集成部分]——否则,编译器将直接生成机器代码,而不使用汇编程序[至少在LLVM中,我最熟悉的编译器中是如此]。因此,编译器产生了一个完整格式的对象文件

    如果您有正确的选项,链接器将被调用,但它是一个单独的可执行文件,它将把对象文件与运行库链接在一起,并“在main之前”启动代码(全局对象构造和类似的,以及“准备调用main”)。这将生成可执行文件

    使用其他选项,编译器将只生成一个对象文件,或以符号形式生成的机器代码的反汇编(
    -S
    选项)

    编译器的后端部分负责代码生成,通常也处理优化和各种代码转换以帮助优化阶段-例如,Clang+LLVM将生成“统一”循环,无论您使用
    while
    for
    goto
    来生成循环


    这有助于更高级的阶段不必识别许多不同形式的循环,并允许编译器生成“好”代码,而不管程序员如何形成循环。[当然,如果您将其变得足够复杂,编译器可能不会完全了解循环的工作方式,也不会很好地进行优化,但对于基本表单之间的直接转换,无论源代码看起来如何,它都将执行相同的最终代码生成]

    预处理器、前端、后端(代码生成器和优化器)、链接器可能重复。今天仍然使用汇编程序是很少见的,太慢了。事实上,编译器不再那么直接了,它可以停在前端生成中间代码。被可以启动后端以实现整个程序优化的链接器消耗。“今天很少使用汇编程序”很好,显然今天没有人使用gcc。或llvm,其目标没有集成汇编程序。或者其他几个…请注意,该序列仅适用于一个编译/翻译单元。构建控制(如make)是第一步。哇,答案太棒了。正是我想要的。非常感谢。