【问题标题】:How can a translation unit access the global scope of another translation unit?一个翻译单元如何访问另一个翻译单元的全局范围?
【发布时间】:2012-12-30 07:49:28
【问题描述】:

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

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

为什么?其他文件如何访问另一个文件的全局范围?全局范围变量不是危险的吗?将变量定义放在其他什么范围内可以解决这样的链接错误?有人在标头中使用此类外部变量声明吗?出于什么目的?

编辑:确切的示例情况在我开头发布的链接中

【问题讨论】:

  • 我不完全确定您要解释什么。您到底要在哪里定义变量?你如何定义它的一个例子会很好。
  • 它在问题开头的链接中
  • 在实际问题的代码中,接受的答案中没有正确的声明,您是否要将变量定义从 main() 函数体外部移动到 main() 函数体?如果,那么哈珀的答案是正确的。该变量仅存在于该函数内部。

标签: c++ header linker declaration extern


【解决方案1】:

一些澄清:

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

有了这个术语,我们现在可以改写您的问题:“一个翻译单元如何访问另一个翻译单元的全局范围”?

引用Linkage 上的维基百科文章:

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

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

您剩下的问题:

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

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

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

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

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

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

【讨论】:

  • 对 1 的补充:锤子在坏人手中与全局变量一样危险,但有时锤子会派上用场。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2011-11-01
    • 1970-01-01
    • 2021-02-24
    • 1970-01-01
    • 1970-01-01
    • 2015-04-05
    相关资源
    最近更新 更多