【问题标题】:Should a function prototype always be in its header file?函数原型是否应该始终在其头文件中?
【发布时间】:2016-03-18 04:28:50
【问题描述】:

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

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

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

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

如果我有一个包含一千多个源 (C) 文件的非常大的项目,我是否应该始终为每个源文件创建一个标头(然后添加函数原型)。然后包含标题以使用功能?

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

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

【问题讨论】:

    标签: c header prototype extern misra


    【解决方案1】:

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

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

    这就是所有(专业)C 程序的编写方式。作为旁注,MISRA-C 也需要这种声音设计。

    永远不应该为函数使用extern 关键字。请注意,像

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

    完全等价于

    extern void func (void);
    

    如果您需要使用某个函数,请包含相关的标头。

    【讨论】:

    • 虽然我同意你对等价的看法,但我更喜欢看到 extern 关键字,因为这明确显示了全局性质。请注意,我更喜欢公共/私有的 C++ 术语而不是外部/静态
    • @Andrew 主要是风格问题。有些人喜欢直白,有些人认为这是多余的。但是,C11 未来的语言方向说“在没有静态存储类说明符的情况下在文件范围内声明具有内部链接的标识符是一个过时的功能。”所以我想在未来的 C 标准中,我们可能无法在不使用 extern 的情况下声明函数。我非常怀疑委员会是否敢采取这一步,因为它会破坏很多现有的代码。我认为这里的基本原理是禁止此类对象类型的标识符,即:“全局”。
    • 确实……还有更重要的事情需要解决,尽管 WG14 对向后兼容性很着迷!
    【解决方案2】:

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

    简短的回答是“是”。

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

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

    【讨论】:

      【解决方案3】:

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

      TL;DR; 答案是肯定的。

      我个人的观点(并且已经写入了几个公司的编码标准)是每个 C 源文件都应该有自己的关联 Header 文件来定义外部接口。

      C 源文件及其关联的头文件共同定义模块 - 但只有头文件声明接口。

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

      {*} 好的,never 不是一个强词,而且可能有例外……但它们应该很少见。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-03
        • 1970-01-01
        • 2021-02-21
        • 1970-01-01
        • 1970-01-01
        • 2012-12-19
        • 1970-01-01
        • 2018-03-07
        相关资源
        最近更新 更多