C++;编译器启动? 如果你有一个C++项目,它有多个源文件,你就可以编译了,编译器从哪个文件开始?

C++;编译器启动? 如果你有一个C++项目,它有多个源文件,你就可以编译了,编译器从哪个文件开始?,c++,compiler-construction,C++,Compiler Construction,我这样问是因为我在图书馆里遇到了一些#包括依赖性问题 编译器应该是:VC2003。它不应该是顺序相关的。唯一相关的步骤是: 每个编译单元都包含它所依赖的内容,并且应该可以单独编译。这意味着,首先,每个CPP文件包括它所依赖的所有头文件;第二,每个头应该依次包含它需要的内容,这样即使它是第一个要编译的头,它也可以编译 链接步骤将所有编译的目标代码放在一起,并构建最终的二进制文件 这取决于环境。通常,“编译器”一次只能处理单个源文件;您可以使用更高级的工具来指导它并计算正确的构建顺序 这类工具的示例

我这样问是因为我在图书馆里遇到了一些#包括依赖性问题


编译器应该是:VC2003。

它不应该是顺序相关的。唯一相关的步骤是:

  • 每个编译单元都包含它所依赖的内容,并且应该可以单独编译。这意味着,首先,每个CPP文件包括它所依赖的所有头文件;第二,每个头应该依次包含它需要的内容,这样即使它是第一个要编译的头,它也可以编译
  • 链接步骤将所有编译的目标代码放在一起,并构建最终的二进制文件

  • 这取决于环境。通常,“编译器”一次只能处理单个源文件;您可以使用更高级的工具来指导它并计算正确的构建顺序


    这类工具的示例可以是make、ant、CMake、SCons、Eclipse和visualstudio。基本检查通常是源代码文件的修改日期,以及定义各种输出文件如何依赖于输入的内置和自定义规则。

    。发布准确的问题。编译顺序是不确定的和任意的,必须对项目的可编译性没有影响。

    不管从哪个文件开始,链接器都会在所有文件编译后解析外部引用。

    正如其他人所指出的那样,编译器编译的顺序不应该有什么不同


    从编译器的角度来看,当您使用
    #include
    编译一个文件时,所包含的文件会在
    #include
    所在的位置插入到正在编译的文件中,并根据需要递归。

    正如其他人所指出的,从概念上讲,从哪个文件开始并不重要。但是,从最新编辑的文件(假设已编辑多个文件)开始,使用依赖关系最多的文件可能会很有用。有些环境,例如Code::Blocks,实际上允许您为源文件赋予权重,以便对编译顺序进行某种控制。

    我能想到的唯一“包含依赖性”问题是递归包含。修复程序通常使用
    #ifdef

    #ifndef INCLUDED_THEFILENAME_H
    #define INCLUDED_THEFILENAME_H
    
    /* content goes here *
    
    #endif
    

    但是你最好详细说明你所面临的问题。

    其他人已经说过,订单不应该有什么不同


    您可能没有意识到的是,编译器编译每个
    .cpp
    .cc
    文件。它不编译头文件。通常,您只包含
    #头文件,而从不包含
    .cpp
    文件,因此顺序无关紧要。每个
    .cpp
    文件都是独立处理的。它包括许多标题,但这些标题从未单独编译,并且通常也不包括其他
    .cpp
    文件。

    make工具构建make文件中指定的依赖项的有向无环图。这通常意味着可执行文件依赖于多个对象文件。对象文件依赖于源文件,每个源文件依赖于头文件,等等

    这基本上生成了一个多路树。树将以可执行文件作为根,通常以头作为叶节点(尽管如果使用某种代码生成器,它也可以将该代码生成器的输入文件作为叶)


    然后,它沿着这棵树从叶节点一直走到根节点,边走边构建。回答说“没关系”基本上是指它可以选择树的任何一个分支先构建。但是,当它选择分支时,它按照该分支指定的顺序生成。

    注意,在用户编写的C++代码中,名为“FixEnEnMaIh”的名称是非法的。宏也是吗?好吧,不管怎么说,这个名字是不相关的。@hacker:你仍然不应该有前导下划线,即使是宏。对于宏来说,大写就足够了,如果在末尾有
    “\u H”
    的话,这对于include-guard来说已经足够了。是的,双下划线是为实现保留的,不管它出现在哪里(在宏、变量名、函数等中。一个典型的原因是编译器可能使用这些名称来定义自己的宏)。单下划线后跟大写字母也是保留的。已更新。感谢评论,标准警察;-)@丹尼尔:您还可以补充一点,即每个标题也应该包含它所依赖的内容,这样即使它是模块包含的第一个标题,它也可以进行编译。谢谢@quamrana,我试图将您的评论包含在我的答案中。我的表述方式是:只包含一个
    #include
    的源文件应始终进行编译(到.o文件)没有错误。我有一个“hcheck”我使用的脚本,它创建了一个.c或.cc文件,其中包含命令行上指定的文件,然后尝试编译它,并在完成后删除临时的.c/.cc文件。非常整洁,Mike!不幸的是,我总是发现模板对此有问题,因为在实例化之前,依赖于名称的符号没有得到解决,您有时会意识到您只是在那时丢失了一些东西…(或者它只是因为一个愚蠢的错误而无法编译…)是的,我没有找到一种处理模板的方法,除了创建一个C++源文件,它包含在包含文件中,并在一个函数中实例化一组测试模板实例。源文件中的测试函数声明为代码>静态< /代码>,因此它不是外部链接的,因此(希望)被链接器省略,因此代码不会变大。无论如何,如果我不能运行类似于
    hcheck
    ,那么我会确保
    #include“foo.h”
    foo.cc
    中的第一个非注释、非空白行。这几乎具有相同的效果(例外: