翻译单位如何访问另一个翻译单元的全球范围?

时间:2012-12-30 07:49:29

标签: c++ header linker declaration extern

我一直在阅读关于链接器如何工作以及围绕此过程的所有内容,以便在this(link)问题中解释我的问题(这很简短,对于引用很抱歉,但它是相关的)。

问题: 如果在标题中我有一个变量声明(使用extern),并且我想在多个源文件中使用此变量(#include其中每个文件中的头文件),我必须在某处提供此变量的定义。问题是,如果我在某些源文件的main函数中提供了一个定义,例如,其他文件仍然没有“看到”这个定义(导致链接错误)。如果我在一个全局范围中定义这个extern变量,它就可以了,并且每个人都能看到它。

为什么呢?其他文件如何访问另一个文件的全局范围?并非全球范围变量危险吗?将变量定义放在其他范围可以解决这种链接错误?有人在标题中使用这样的外部变量声明吗?为了什么目的?

修改:确切的示例情况位于我在开头发布的链接中

2 个答案:

答案 0 :(得分:5)

一些澄清:

您所谓的“文件”更适合称为翻译单元。涉及多少文件并不重要。实际上,可以重新编译同一个文件(比如使用不同的#defines等)

有了这个词,我们现在可以改写你的问题:“翻译单位如何访问另一个翻译单位的全球范围”?

引自维基百科关于Linkage的文章:

  

如果名称具有外部链接,则名称表示的实体可以使用相同名称的不同声明从另一个翻译单元引用,并使用不同声明从同一翻译单元内的其他范围引用。

换句话说:通过确保名称作为外部链接,它在全局范围内,并且对于程序而言是全局的,而不是翻译单元。

您剩下的问题:

  1. 全球范围变量不是危险的吗?

    我永远不会使用“危险”这个词来描述它们,因为我会使用某些具有安全漏洞的标准库函数等。但我会说这通常会导致代码设计非常糟糕,并且在特别是全局变量,多线程代码中的许多令人头疼的问题。一个好的规则:除非你有充分的理由不这样做,否则请避开它们。

  2. 如何避免链接错误(在其他一些范围内)

    此处没有其他魔法声明:它在翻译单元外部可见(外部)或不可见(静态)。您可能要求的是:“让其他模块访问变量的正确方法是什么?”答案是:编写一个访问器函数(甚至更好,一个用方法管理该数据的类)。

  3. 谁使用这些东西以及用于什么目的?

    始终是一个激烈争论的话题。许多人建议完全避免,但是你很难在一个足够大的项目中找不到外部人员。最好的理由通常归结为纯粹主义者忽视的东西:与遗留系统的兼容性,性能,调试器和其他内省工具的轻松访问......当然,只是因为它很容易,它被理解,它只是起作用。

答案 1 :(得分:3)

放置变量in the main function时,您可以定义在该函数中可见的局部变量。

您必须在一个源文件中的文件范围内定义变量。