(隐藏?)影响 C/C++ 编译的 MS Visual Studio 设置

Posted

技术标签:

【中文标题】(隐藏?)影响 C/C++ 编译的 MS Visual Studio 设置【英文标题】:(Hidden?) MS Visual Studio settings affecting C/C++ compilation 【发布时间】:2014-08-12 22:34:35 【问题描述】:

我有一个 C++ 文件,它在一个项目中编译得很好,但在另一个项目中却没有。该文件是两个项目中完全相同的 C++ 文件。

这两个项目都是基于 MFC 对话框的项目。它们的 stdafx.h 文件略有不同...但是如果我准备破坏项目的其余部分,我可以使它们完全相同...并且仍然会出现此编译器错误。同样,它们具有相当不同的包含路径,但如果我破坏更多项目并使包含路径相同,我仍然会收到错误。不用说,我已经使我的所有预处理器指令都相同......我仍然得到错误。

所以,据我所知,我只需要编译器开关。我已经使它们完全相同(在合理范围内 - 我没有费心更改/Fp/Fd/Fo 输出文件),但它仍然拒绝编译。是否有任何“隐藏”设置或其他可能影响编译的内容?

[注意:包含以下内容主要是出于历史原因 - 它在最初提出这个问题时导致无意过分强调,因此导致可预测的 cmets 和答案无助于解决预期的“何时相同”不一样?”问题]

错误本身是错误 2894(模板不能有“C”链接)。我理解这个错误,但不知道它是如何/为什么发生的。它出现在与 C 库有关的一堆 C 头文件中。它们都整齐地包装在extern "C" ... 声明中,并正确应用了#ifdef __cplusplus。但是extern C ... 不是我很熟悉的东西,所以……extern "C" ... 有什么特别之处吗?

【问题讨论】:

我的猜测,鉴于信息,它只能是一个猜测,是您将 C++ 头文件包含到扩展名为 .c 的文件中,并且编译器将代码编译为“ C”而不是“C++”,并且错误不是直接因为 extern "C" ... 本身 - 但也可能是您在 extern "C" ... 块中包含 C++ 标头。解决此类问题的唯一好方法是开始减少编译的代码,直到有几十行左右,此时它通常非常明显。 复制损坏的项目并开始将其缩小到最小大小以产生错误。理想情况下,您将源代码压缩到一个包含 wspapi.h 标头的单个 cpp 文件。然后开始减少项目选项。 你试过谷歌搜索extern "C"吗? @MatsPetersson - 单个文件是一个 .cpp 文件,在两个项目中是相同的。此外,我已将代码缩减为 3 行 - 包含三个头文件(继续包含其他头文件)并且差异仍然不明显。但我会关注差异,而不是extern "C",因为最后,C 编译器在一个有效的条件下被调用,而在另一个无效的条件下被调用,并且它被调用而不知道项目中的其他所有内容,是不是吗? 好吧,然后开始减少包含的内容,直到包含文件中只有十几行...如果到达那里后它不是很明显,我会感到非常惊讶。 .. 【参考方案1】:

如果在相同条件下编译单个 C++ 文件,则会导致相同的结果。不管它是在一个有零个其他文件还是有一百个其他文件的项目中 - 编译器会单独编译每个文件。

因此,如果单个 C++ 文件编译时结果不同,那是因为:

它实际上不是同一个 C++ 文件,或者 其实编译条件不一样。

通过将/showIncludes 指定为“高级”编译器选项,您可以确切地看到 Microsoft Visual C++ 编译器认为您的“单个”C++ 文件是什么。您可能会惊讶地发现您的“相同”C++ 文件有多么不同(这里就是这种情况)。

同样,您可以在 Visual Studio 中项目属性的C/C++ 选项列表底部的Command Line 摘要下看到明确的 C++ 编译器条件。

【讨论】:

您的问题是关于如何找到应用于编译器的选项或如何解决您的问题?这并没有回答他后者,也没有说明这些信息如何帮助您解决问题。对我来说似乎是XY 问题 我不认为这是一个 XY 问题(因此为什么我首先给你的原始问题投了赞成票),但它确实似乎你试图过度概括问题和解决方案都超过了有用的程度。如果您使用相同的包含路径和相同的编译器开关编译相同的文件,为什么包含文件的列表不同?【参考方案2】:

wspapi.h 在其内部 extern "C" 部分之外包含一些 C++ 模板代码。如果您要将标头外部包装在 extern "C" 声明中,您会破坏它。

例如,您不能这样做:

extern "C"

    #include <wspapi.h>

类似地,如果前面的标头或代码未能终止 extern "C" 块以便标头的所有内容都被赋予 C 链接,则会出现相同的情况。

简而言之,wpsapi.h 已包含在 C 链接块中,它与“隐藏选项”无关。

【讨论】:

很好 - 不会解决我的特定问题,但知道有用。 @omatai :你不是很有启发性,因此这不是一个好的 SO Q&A。当 extern "C" 处于活动状态时包含模板代码时会出现编译器错误,所以如果这不是原因,我会感到惊讶 - 即使机制与示例代码片段不同。 也许有人可以写得更好......但我想问题是“相同的事物如何导致不同的结果?”它恰好涉及extern "C",但它可能涉及aardvarks。我无法阻止人们关注那些无关的症状,但我觉得我不得不提到它(把它放在标题之外;只在最后提到)以表明我实际上已经对具体错误的意思。我提出问题以试图启发 - 如果这可以节省 24 小时让我感到沮丧的人,那肯定是 SO 的目的,不是吗?

以上是关于(隐藏?)影响 C/C++ 编译的 MS Visual Studio 设置的主要内容,如果未能解决你的问题,请参考以下文章

一个eclipse里面如何建立两个互不影响的project, 如建立一个Cproject和一个javaproject?

在线编译器对计算机内存的影响

在 docker 的不同内核中编译代码会受到啥影响?

C#-C#-#define条件编译

c++程序不同环境就很卡

Windows 隐藏控制台