函数原型是否应始终位于其头文件中?

时间:2016-03-18 04:28:51

标签: c header prototype extern misra

假设我们有一些C源文件,例如file1.cfile2.cmain.c。我们的功能如下:

file1.c
      |---> file1Func1()
      |---> file1Func2()

file2.c
      |---> file2Func1()
      |---> file2Func2()

,主文件使用这些功能。现在,我很自然地在头文件file1.hfile2.h中创建和添加相应的函数原型,然后在main.c中包含这些头以使用这些函数。

如果我有一个包含超过一千个源(C)文件的非常大的项目,我应该总是为每个源文件创建一个标题(然后添加函数原型)。然后包括使用函数的标题?

或者使用 extern 来使用在别处定义的函数(在其他一些源文件中)并依赖链接器在链接时搜索并从目标文件中获取函数?

注意:使用后一种方法会触发没有函数原型的MISRA警告。

3 个答案:

答案 0 :(得分:7)

作为接口一部分的所有函数,即由另一个模块调用的函数,应该在头文件中具有函数原型。最好与记录如何使用该功能的评论一起使用。

不属于界面且仅在文件内部使用的函数不应在标题中包含原型。对于此类函数,请将原型声明在c文件的顶部,并将其声明为static

这就是所有(专业)C程序的编写方式。另外,MISRA-C也要求这种声音设计。

永远不应该有理由将extern关键字用于函数。请注意像

这样的函数原型
void func (void);

完全等同于

extern void func (void);

如果您需要使用某个功能,请包含相关标题。

答案 1 :(得分:1)

  

如果我有一个包含超过一千个源(c)文件的非常大的项目,我应该总是为每个源文件创建一个标题(然后添加函数原型)。然后包括标题以使用函数?

简短的回答是“是”。

稍长的答案是“是的,但您可以省略头文件中的函数,这些函数是源文件中其他函数的实现细节”。

在头文件中声明函数并#include头文件可确保函数定义和函数调用保持同步。否则,很容易出错,这些错误会在链接时而不是在编译时捕获。

答案 2 :(得分:0)

  

我应该总是创建一个标题(然后添加函数原型)   每个源文件。

TL; DR; 回答为是。

我的个人意见(以及已经写入多个公司编码标准的意见)是每个C源文件都应该有自己的关联头文件来定义外部接口。

C源文件及其关联的Header文件一起定义模块 - 但只有Header文件声明了接口。

所有全局对象(包括函数原型)都应在头文件中声明;我还提倡extern关键字永远不应该(*)在C源文件中使用,因为这是(恕我直言)打破模块的声明接口。

{*}好吧,永远不是一个强有力的词,可能有例外......但它们应该很少而且很远。