【问题标题】:Visual C++ Precompiled Headers errorsVisual C++ 预编译头错误
【发布时间】:2010-11-26 16:47:57
【问题描述】:

更新:

在我的头文件中包含 stdafx.h 有什么影响?


我在 Linux/Eclipse CDT 中开始了一个 C++ 项目,并将其导入 Visual C++/Windows。

在 Visual C++ 中,我开始使用预编译头文件来加快编译速度,并定义了 stdafx.cpp 和 stdafx.h。

这是我的 stdafx.h

#pragma once

#include <string>
#include <vector>
#include <map>
...

还有我的 stdafx.cpp

#include "stdafx.h"

在每个 .h 和 .cpp 文件中,我都有以下内容:

#pragma once //if in a header file
#include "stdafx.h"

对于发布和调试,我都有“创建预编译头文件 (/Yc)”。它在调试模式下编译良好,但在发布模式下它会不断报告

error LNK2005: ___@@_PchSym_@00@UfhvihUaszlaDUwlxfnvmghUnnlUhixUnnlPeDUnnlPeDUivovzhvUvmgrgbOlyq@ already defined in A.obj

如果我同时切换到“使用预编译头”,我会同时进入调试和发布

fatal error C1854: cannot overwrite information formed during creation of the precompiled header in object file:

有人知道怎么回事吗?

【问题讨论】:

  • 顺便说一下,我创建了一个新的测试项目并将其 PCH 设置与我的进行了比较。它的设置是使用 PCH。该项目以某种方式编译得很好。

标签: c++ visual-studio visual-c++ header precompiled-headers


【解决方案1】:

您只为 stdafx.cpp 放置了“创建预编译头”。然后对所有其他“.cpp”文件“使用预编译头文件”。最后,在每个“.cpp”文件的开头加上include "stdafx.h"(通常不在头文件中。

【讨论】:

  • 我只能设置一个配置范围的 Create PCH 或 Use PCH。
  • 在VS中,您可以右键单击单个文件并选择“属性”。然后在“C++ -> Precompiled headers”下,您可以将值设置为“create”或“use”。配置范围设置用作默认设置 - 您可能应该将其设置为“使用”,然后为 stdafx.cpp 覆盖它
  • 那么在我的头文件中包含stdafx.h有什么影响呢?
  • 实际上没有任何效果,因为标头本身没有定义可编译单元,它们只是其他可编译单元的一部分。
  • 我知道这是一个老问题,但我对“通常不在头文件中”部分感到困惑。您是说要定期包含所有必要的文件,例如 example.h 和 example.cpp 应该包含预编译的头文件和 example.h?这是否意味着 example.h 中包含的文件被编译了两次——一次在 pch 中,一次在 example.h 中?
【解决方案2】:

/Yc 编译器选项用于为编译操作创建预编译头。 /Yu 选项指示编译器使用预编译的头文件。

您将始终在项目设置中使用/Yu 选项。 在stdafx.cpp 文件的属性页中,将设置/Yc 选项。

了解每个.cpp 文件都有单独的编译选项很重要 .

有关 /Y 选项的详细信息,请参阅 here

【讨论】:

    【解决方案3】:

    您将#pragma once 放在#include "stdafx.h" 之前,我认为这会导致编译器忽略#pragma once 指令。

    另外,我认为您根本不应该将 #include "stdafx.h" 行放入头文件中。

    【讨论】:

    • 是的,您通常将 #include "stdafx.h" 作为每个 .cpp 文件的第一个包含。我认为它实际上可能必须是第一个非评论行。
    • 所以基本上我必须在 PCH 中包含我自己的头文件?我自己的头文件中引用的昂贵的编译头文件(boost)呢?
    • 例如,如果我在 stdafx 和 my_class.h 中都引用了 Boost,在 my_class.cpp 中 my_class.h 中引用的 Boost 将被跳过,因为 stdafx 已经引用了它?
    • 即使头文件必须包含在其他地方,也只需要作为预编译的一部分进行处理。您在 PCH 中包含标头以最小化处理,您在其他地方包含标头以提供类型信息和定义构造。包含有不同的目的。
    • 虽然这个答案指出了一些问题,但它实际上并没有回答链接器错误的问题。
    【解决方案4】:

    使用“stdafx.h”的结果不受 PreCompiled Header 系统的影响。如果关闭 Create PCH/Use PCH,代码将编译并创建相同的输出,但速度较慢。这也是你可以在可移植代码中使用它的原因(不像#pragma once

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-28
      • 1970-01-01
      • 1970-01-01
      • 2010-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多