#pragma hdrstop without parameter 在多个文件中使用时有啥作用?

Posted

技术标签:

【中文标题】#pragma hdrstop without parameter 在多个文件中使用时有啥作用?【英文标题】:What does #pragma hdrstop without parameter do when used in multiple files?#pragma hdrstop without parameter 在多个文件中使用时有什么作用? 【发布时间】:2011-09-02 11:38:52 【问题描述】:

#pragma hdrstop(无文件名参数)放在几个源 (cpp) 文件中的实际价值(“它的作用”)是什么?

请注意,MSDN docs 对我来说(再一次)像泥巴一样清晰。

编辑/注意:我问这个,因为this answer 和它链接的文章似乎建议这样做。但我不明白每个编译单元都有一个 单独的 pch 文件有什么好处。

【问题讨论】:

【参考方案1】:

原始问题的答案是,在既不设置 /Yc 也不设置 /Yu 的文件中使用 #pragma hdrstop 的目的是忽略它,因此您可以设置构建配置,在没有预编译头文件和其他构建的情况下构建使用预编译头文件构建的配置,您根本不需要更改代码或包含的头文件。

更多细节...

MSDN 上的注释说“hdrstop pragma 让您可以额外控制预编译文件名和保存编译状态的位置。”这是真的,但它究竟有多大用处并不是特别明显......

简而言之。

将 #pragma hdrstop 放入未使用 /Yc 或 /Yu 编​​译的源文件中根本没有任何效果。 如果您为文件设置了 /Yu,则 hdrstop 会告诉编译器丢弃出现 hdrstop 的行之前的所有内容,并改为插入预编译的标头。 如果为文件设置了 /Yc,则 hdrstop 表示保存所有已编译状态的所有内容,直到 hdrstop 显示为预编译头的行。

诀窍是使用 /Yc 和 /Yu 而不使用可选的头文件名;只需选中“使用”或“创建”单选按钮并将“通过标题”编辑框留空(或编辑项目文件...)。

所以您有 1 个文件,可能称为 PrecompiledHeader.cpp,其中包含您想要包含在预编译头文件中的头文件,并且在包含文件列表的末尾有 #pragma hdrstop。这个 ONE 文件是用 /Yc 编译的。

然后,在预编译头文件中的包含文件之后,您将拥有所有其他带有#pragma hdrstop 的 cpp 文件。这些文件都是用/Yu编译的。

这会导致 PrecompiledHeader.cpp 构建您的(在此示例中)单个 pch 文件以及使用该单个 pch 文件的所有其他文件。

这样做的好处是您的所有文件都不需要包含“全局”预编译头文件构建头文件 - 所以不需要 stdafx.h 或其他任何东西。这意味着您可以设置一个构建配置,该配置在没有预编译头文件的情况下构建,其中所有#pragma hdrstop 行都被简单地忽略。

这很“好”,因为这意味着您可以拥有一个“无预编译”构建配置,让您可以快速开发(您可以更改单个标头而不强制重建世界)和其他“正常”配置,请使用预编译的头文件。

【讨论】:

谢谢。非常感谢你! ...现在,嗯... “然后,您的所有其他 cpp 文件都带有 #pragma hdrstop 在您的预编译头文件中的包含文件之后。” - 这是否意味着其他文件需要想知道预编译头文件中的内容,以便他们可以将其包含拆分到 hdrstop 行之前和之后? 如果你这样做效果会更好。但你不必。如果您有一个位于#pragma hdrstop 之上的文件,而该文件不在您的预编译头文件中,那么您将在您的预编译构建中遇到构建错误。然后,您可以决定它是否被广泛使用以保证在 precomp 中的存在。【参考方案2】:

#pragma hdrstop 之前的所有代码都将成为预编译头文件的一部分。如果没有给定文件名参数,则头文件的名称将是源文件的基本名称,扩展名为 .PCH,如the documentation 中所述:

预编译头文件的名称是根据 以下规则,按优先顺序排列:

    /Fp 编译器选项的参数

    #pragma hdrstop 的文件名参数

    带有 .PCH 扩展名的源文件的基本名称

因此,如果您在名为 blah.cpp 的文件上使用它,它将生成一个名为 blah.pch 的文件,IFF 使用 /Yc 编译(应该只设置一个文件)。

【讨论】:

当您绕过选项 0、1 和 2 时会发生这种情况。使用 /Yu 非常普遍,选项 0。【参考方案3】:

如果在您的 C/C++ 项目中不使用 #pragma hdrstop,您可以使用专用的 .cpp 文件作为创建的 .pch 的源文件。

如果在要创建 .pch 文件的 .cpp 文件中使用 #pragma hdrstop,则 .cpp 文件可以在 #pragma hdrstop 行之后包含其他有用的内容。当您第一次使用 /Yc 编译选项编译此 .cpp 文件时,您将获得 .pch 文件和 .obj 文件。当您更改.cpp文件并使用/Yu编译选项重新编译它时,编译器将#pragma hdrstop行之前的内容替换为.pch文件并重新编译#pragma hdrstop行之后的部分,创建一个新的.obj文件,节省编译时间。您的项目只有一个源文件非常有用。

对于仅使用预编译头文件的源文件,#pragma hdrstop 是编译器的标志,应该将哪部分替换为 .pch 文件,因此您无需在 /Yu 编​​译选项中指明头文件名。

【讨论】:

谢谢。这个答案很有意义。所以你必须用不同的编译器开关编译 same cpp 文件才有意义? 是的。一个 C/C++ 项目可以使用多个 .pch 文件。您可以通过 /Yu 编​​译选项或 #pragma hdrstop 为每个源文件指定 .pch。 我明白了。我的意思是:为了让这个有意义,我们有一个总是用/Yu 编译的U.cpp 和另一个总是用/Yc 编译的C.cpp或者我们是否有一个单独的UC.cpp/Yc 编译一次,然后用/Yu 编译一次??

以上是关于#pragma hdrstop without parameter 在多个文件中使用时有啥作用?的主要内容,如果未能解决你的问题,请参考以下文章

EnumPorts函数枚举计算端口

#pragma 警告(push) 没有 #pragma 警告(pop)

用C++ Builder实现一组数组的排序与插入操作

LeetCode 3. Longest Substring Without Repeating

在另一个并行循环中调用函数时,函数中的“pragma omp parallel for”无效

[Coding Made Simple] Number without consecutive 1s in binary representation