【问题标题】:Using extern function instead of including a header defining that function使用 extern 函数而不是包含定义该函数的标头
【发布时间】:2020-09-25 16:13:11
【问题描述】:

根据这个问题What's the difference between using extern and #including header files?,我知道extern 对变量非常重要,我完全明白使用extern 变量的意义和基本原理。

但是我仍然无法理解extern 函数背后的想法,我知道它是如何工作的以及链接以及所有这些,但是如果我们在头文件中定义了函数会不会一样?

我只能想到使用动态链接库的好处,因此我们不必在每次库更改时都构建我们的应用程序,但是为什么我会不遗余力地将extern 与静态链接库一起使用而不仅仅是包含头文件。

更新:

我知道定义和声明的区别。

【问题讨论】:

  • 注意:默认情况下,所有函数都是extern 链接,除非明确提及static,否则它仅限于文件范围。这些与前向声明(即放入头文件)有什么关系?
  • 您似乎混淆了“定义”和“声明”这两个术语——它们不是同一个东西,在 C 和 C++ 中具有非常特定的含义
  • 我不太明白这个问题。是否在头文件中或其他地方声明一个函数,以及是否声明它extern,是单独的问题,不是吗?
  • 您通常不需要在函数声明上使用extern,无论它们在哪里。人们经常这样做,出于风格或习惯的原因。 Linux 内核头文件中充满了externs
  • (a) 编辑问题以澄清是否询问了声明和/或定义。如果没有询问头文件中的定义,请删除对定义的提及。 (b) 编辑问题以添加示例。 (c) 编辑问题以删除短语“extern function”。我认为在这一点上,您正在询问“使用extern 的函数声明”。 (c) 说明您认为动态链接库和与之相关的静态链接库之间有什么区别。

标签: c++ c


【解决方案1】:
  1. 在预处理中将头文件添加到您的源代码.c。 C 编译器编译一个大文件,并将所有头文件添加到该文件中。 https://godbolt.org/z/Eo3n1Y

  2. 在您的源文件中提供与 .h 文件中相同的函数原型和外部对象声明将具有相同的效果。

  3. extern 与变量一起使用显示编译器该变量是在项目中的某处定义的。它可以稍后在同一个编译单元(源文件)(https://godbolt.org/z/4vM1of)或另一个中。访问将在链接期间得到解决。

  4. 函数定义为extern。如果函数没有在调用它的位置之前定义或在其他编译单元中定义,则现代 C 需要函数原型。 https://godbolt.org/z/d91P6q

【讨论】:

    【解决方案2】:

    理解这一点的先决条件:研究difference between function declaration and function definition

    我知道 extern 对于变量非常重要

    这不是真的。 extern 是一个几乎是多余的语言功能,用途非常有限。正确设计的程序不需要它——它只用于非常特殊的场景。如果你发现自己在日常编程中使用它,那就意味着你的程序设计有缺陷。

    但是我仍然无法理解 extern 函数背后的想法,我知道它是如何工作的和链接以及所有这些,但是如果我们在头文件中定义函数,那不就一样了吗?

    实际上,它与在头文件中声明函数 相同。 void func (void) 等函数声明也隐含为 extern,您也可以键入 extern void func (void);,这是 100% 等效的。编写程序的正确方法是在头文件中提供函数声明。

    您很可能根本不需要在任何地方使用extern

    【讨论】:

    • 我完全不同意变量的情况。
    • 我从事 C 编程和系统设计工作已有 20 多年了,而我在这段时间里只使用过一次或两次extern。有了这种经验,我可以自信地挑战你,提供一个你认为需要extern 的例子,我可以指出你整体程序设计中的缺陷。当然有一些特殊情况,如答案中所述,内存映射硬件寄存器的非标准微控制器寄存器映射有时可以使用它。这是我所知道的唯一有效的场景。
    • 拥有代表全局对象的全局状态是合理的,因为没有更好的词。想到了标准输入和标准输出,以及它们的 c++ 对应物。
    • @Lundin I've worked with C programming and system design for over 20 years, and I've only used extern once or twice in all that time. 这个问题不是关于良好的编程实践以及全局对象的好坏,而是关于语言本身。
    • @OmarKhalid 那里有许多著名的“高调”C 库,它们的编写很糟糕。 Windows API 和 Unix/Linux API 就是两个完美的例子。仅仅因为那些产品是成功的,并不意味着它们的成功是因为它们编写的代码非常棒。
    猜你喜欢
    • 2012-02-24
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 2020-01-23
    相关资源
    最近更新 更多