需要澄清一下#pragma once
Posted
技术标签:
【中文标题】需要澄清一下#pragma once【英文标题】:Need some clarification on #pragma once 【发布时间】:2014-02-18 03:00:55 【问题描述】:我已经搜索了所有关于什么的澄清 #pragma 一次 对于我仍然存在的一些问题,实际上确实找到了并且无法找到明确的答案。
确实 #pragma 一次 确保它包含在其中的头文件只被调用一次,以及包含在所述头文件中的头文件尚未包含在内?另外,如果只调用一次,这是否意味着需要特定标头的 .cpp 文件将无法访问它?如果头文件标有 #pragma 一次 并包含在 .cpp 中,该头文件可以在其他地方再次使用吗?
这些是我没有找到的澄清。抱歉,如果有文档在某处澄清了这一点,但我真的找不到任何足够具体的东西。
【问题讨论】:
请注意,虽然得到普遍支持,但在技术上它并不是标准的。 【参考方案1】:#pragma once
仅保护单个翻译单元中的单个文件,不包括其包含的子层次结构。 (但是,如果阻止了文件的第二次包含,则它没有机会双重包含其他任何内容。)
您仍然可以从另一个 .cpp
再次包含它。
文件通常由它的 inode 号来标识。
请注意,#pragma once
严格来说是非标准的,大多数人仍然更喜欢传统的 #ifndef
标头保护。
【讨论】:
这对我有一点帮助,因为我在玩directX,所以代码首先不是平台移动的。我想我现在需要了解的是什么是翻译单元,我敢打赌它有据可查,而且还特定于编译器? @ManicCure,简而言之,它是一个 (cpp) 文件,所有标题都直接或间接包含在其中。如果您想要一个标准定义,程序的文本保存在本国际标准中称为源文件的单元中。源文件连同所有头文件 (17.6.1.2) 和通过预处理指令#include 包含的源文件 (16.2),减去任何条件包含 (16.1) 预处理指令跳过的任何源代码行,称为翻译单元。standard => supported
-->
en.wikipedia.org/wiki/Pragma_once
@Andreas 得到广泛支持!= 良好实践。有很多争论在这里不值得重复。【参考方案2】:
#pragma once
导致当前源文件在单个编译中仅包含一次。
本质上类似于#include
guards。
【讨论】:
好的,你能帮我理解什么是编译吗?因为这对我来说听起来像是编译器将忽略同一头文件的所有包含,即使它可能需要并且不会导致编译器错误,从而导致编译器错误。使困惑?我知道我是……#include 守卫有非常明显的逻辑; #pragma once 不会,因为编译器执行的操作没有传达给代码的阅读者。【参考方案3】:#pragma once 是否确保它包含的头文件只被调用一次,以及包含在所述头文件中的头文件尚未包含在内? em>
编译指示不会影响其他标题。如果带有 pragma 'a.h' 的标头包含 'b.h',则可以通过第三个标头或直接包含 'b.h'。
另外,如果只调用一次,是否意味着需要特定标头的 .cpp 文件将无法访问它?
您可以在任何地方添加标题,次数不限。
如果头文件用#pragma 标记过一次并包含在 .cpp 中,那么该头文件可以在其他地方再次使用吗?
是的,这是使用标题的正常做法。
问题在哪里?
如果您确实需要多次包含标头,并且每个包含执行的操作与不使用 pragma once 或哨兵宏不同。这些情况并不常见。
pragma once
的一个好处是它可以让您避免出现错误,例如拥有 2 个偶然具有相同哨兵宏的头文件。当 2 个头文件具有相同的文件名和相同的宏名称编码样式时,可能会发生这种情况。
【讨论】:
此后,#pragma once 可以包含在您创建的每个头文件中,并且假设您包含所有正确的文件,您将永远不会遇到未声明的标识符的问题? @ManicCurepragma once
只防止重复声明。包括所有正确的文件是棘手的部分。问题是,如果包含太多错误的依赖项,C++ 会变慢。
没错。如果您想要更好的编译速度,请阅读预编译头文件。但这是另一个问题。以上是关于需要澄清一下#pragma once的主要内容,如果未能解决你的问题,请参考以下文章
#pragma once vs. include guards [重复]
C++中防止多次包含头文件:#pragma once和 #indef的区别
C++中防止多次包含头文件:#pragma once和 #indef的区别