关于编译的问题

时间:2013-04-25 19:53:30

标签: c compilation conventions

我一直想知道编译项目的最佳方法是> 1000行代码。我只是有一些关于编制项目的最佳方法的基本问题。我正在使用GCC,如果它有所作为。我的问题是:

  • 在多个源文件中包含库会导致函数被复制两次吗?

我的意思是,如果我有两个这样的文件:

Souce.c

#include<stdio.h>
...
void static test_func( ){ printf( "Hey!" ); }

Source2.c

#include<stdio.h>
...
void static test_func( ){ printf( "Hey!" ); }

函数printf是否会被复制到可执行文件中两次?我想我想避免这种情况,因为很多时候我会有多个共享相同头文件的源文件,我想知道这是不是一个坏习惯。

有一次,我只是通过使用它来包含其他源文件:

由source.c

#include<stdio.h>
#include "source2.c"

但我不确定这是否也是一种不好的做法。这引出了另一个问题:

  • 包含源文件是一种不好的做法吗?

注意:通过不良做法,我的意思是,如果某些事情违反惯例或导致某种低效率。

编辑:我刚刚读到这些库是在文件之间共享的。我的客人,这意味着我的第一个问题的答案是否定的。但是,如果包含使用预处理器的源文件是一种常见的做法,我很好奇。

3 个答案:

答案 0 :(得分:1)

在静态链接期间,库函数仅包含一次。如果库是动态的,则根本不添加任何副本,仅添加动态链接信息。

包含.c文件很奇怪,除非您有特定的理由这样做。其中一个原因是外部模块测试程序,您根本不需要模块中的main功能,但同时为了正确测试它, main需要访问其他文件无法访问的所有文件静态数据。

答案 1 :(得分:1)

在文件中多次包含库不会在最终可执行文件中多次包含它

链接器负责解析函数,当它发现它已经知道函数并且它已经包含它时,它不会尝试再次将它包含在静态链接中。同样链接器将确保它只包含必要的包含静态链接中特定定义的文件。

在动态链接中,链接器会将运行时应用程序所需的动态库文件加载到内存中

答案 2 :(得分:1)

请注意,stdio.h等库头文件仅包含printf等函数的声明;它们不包含这些函数的实际代码。当链接所有目标文件和相关库以形成最终可执行文件时,会在链接时添加printf等函数的实际代码。

包含您的示例中的源文件通常被视为不良做法,尽管可能有特定的用例;我只是想不出任何好事。您冒着重复定义错误的风险,并且不必要地重建代码。编译器可能限制一次可以消化的代码量;包括包含源文件的源文件的源文件可能会导致构建时间过长或更糟。已经有一段时间了,但是我看到编译器在非常大的文件上窒息,特别是如果你试图优化输出。

将代码拆分为多个源文件的好处是,如果我只在一个文件中更改某些内容,我(通常)不必重建整个项目(当然,这取决于更改的内容);我只需要重新编译那个文件并重新链接。