编译&用C ++链接多个文件

时间:2010-09-29 09:40:26

标签: c++ g++ compilation

我的一位“非程序员”朋友最近决定制作一个C ++程序来解决一个复杂的机械问题。

他在一个单独的.cpp文件中编写了每个函数,然后将它们全部包含在主源文件中,如下所示:

main.cpp中:

#include "function1.cpp"
#include "function2.cpp"
...
int main() 
{
...

}

然后使用单个gcc行编译代码

g++ main.cpp    // took about 2 seconds 

现在,我知道这应该可行,但我不确定是否将.cpp文件直接包含在主程序中是一个好主意。我已多次看到以下方案,其中所有函数原型都使用extern关键字进入头文件,如下所示:

funcs.h:

extern void function1(..);
extern void function2(..);
...

main.cpp中:

...
#include "funcs.h"
...

&安培;编译:

g++ -c function1.cpp
g++ -c function2.cpp
...
g++ -c main.cpp
g++ -o final main.o function1.o function2.o ...

我认为这个方案更好(使用makefile,ofcourse)。有什么理由可以让我的朋友这么说服他?

2 个答案:

答案 0 :(得分:21)

人们按对象编译对象的主要原因是节省时间。高级本地化代码更改通常只需要编译一个对象和重新链接,这可能更快。 (如果公共代码中的更改触发更全面的重新编译,编译太多标题中的对象或冗余地实例化相同模板,实际上可能会更慢)。

如果项目太小以至于可以在2秒内编译,那么传统方法实际上并没有太大的好处,尽管做出预期可以节省开发人员的时间 - 就像你和我们这样:-)。平衡这一点,维护一个makefile也需要时间,尽管为了方便地捕获包含目录,库,编译器开关等,你最终可能会这样做。

对书面/生成代码的实际影响:

  • cpp文件通常首先包含它们自己的标题,这提供了一个完整性检查,标题内容可以被其他客户端代码独立使用:将所有内容放在一起,并且命名空间已被“污染”,包含来自早期标题/实现文件< / LI>
  • 当所有内容都在一个翻译单元中时,编译器可以更好地进行优化(对于leppie的评论+1,做同样的...)
  • 静态非成员变量和匿名名称空间对于翻译单元是私有的,因此包括多个cpps意味着分享这些,无论好坏,(亚历山大+1: - ))
  • 说cpp文件定义了一个函数或变量,它的标题中没有提到,甚至可能在匿名命名空间或静态:稍后在翻译单元中的代码可以自由地调用它而不需要破解它们自己的前向声明(这很糟糕 - 如果函数是打算在它自己的cpp之外调用那么它应该在标题中并且在它的翻译单元的对象中有一个外部公开的符号)

BTW - 在C ++中,您的标题可以在不明确使用extern关键字的情况下声明函数,这样做是正常的。

答案 1 :(得分:6)

第二种风格的原因是因为每个.cpp文件都可以单独处理,有自己的类,全局变量等,而且没有冲突风险。

自动链接所有.cpp文件(如MSVC)的IDE也更容易。