只有.h在某个目录中时,g ++才会神秘地失败

gga*_*ett 6 c++ macos xcode g++

我在新的OSX 10.4.11 + Xcode 2.5安装中遇到了一个非常奇怪的问题.我把它减少到一个最小的测试用例.这是test.cpp:

#include "macros.h"

int main (void)
{
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

这是macros.h:

#ifndef __JUST_TESTING__
#define __JUST_TESTING__

template<typename T> void swap (T& pT1, T& pT2)
{
    T pTmp = pT1;
    pT1 = pT2;
    pT2 = pTmp;
}

#endif //__JUST_TESTING__
Run Code Online (Sandbox Code Playgroud)

如果两个文件都在同一目录中,则编译并正常工作.但是,如果我将macros.h放在/ usr/include/gfc2(它是我使用的自定义库的一部分)并更改test.cpp中的#include,则编译失败并显示以下错误:

/usr/include/gfc2/macros.h:4: error: template with C linkage
Run Code Online (Sandbox Code Playgroud)

我研究了这个错误,大多数评论都指向了一个"悬空的外部C",这似乎根本就不是这样.

我在这里完全失败了.g ++是否出于某种原因假设所有内容/usr/include/gfc2都是C,即使它包含在一个.cpp文件中,并不是说extern"C"在哪里?

有任何想法吗?

编辑:如果我使用完整路径,它确实编译#include,即#include "/usr/include/gfc2/macros.h"

EDIT2:它没有包含错误的标题.我已经验证了这一点使用cpp,g++ -E和重命名macros.h,以foobarmacros.h

Joh*_*all 7

G ++可能确实假设/ usr/include中的所有内容都是C.尝试使用-E编译代码并研究预处理器输出中的行标记:

g++ -E test.cpp | grep '^#'
Run Code Online (Sandbox Code Playgroud)

你可能会看到类似的东西

# 1 "/usr/include/gfc2/macros.h" 1 3 4
Run Code Online (Sandbox Code Playgroud)

4是暗示G ++应该包装所有内容的预处理器extern "C",假设你的平台在/ usr/include中的古老头文件包含在C++之前.请参阅CPP手册中的预处理器输出.

这些天G ++大多忽略了这个提示,因为大多数平台的C头不再是古老的.请参阅NO_IMPLICIT_EXTERN_CGCC Internals手册中的目标宏.但可能是这个旧版本的Xcode没有配置GCC NO_IMPLICIT_EXTERN_C,因此正在监听预处理器的提示.(这是在GCC本身构建时设置的 - 我不认为有一个命令行开关来覆盖它.)

您可以通过包装头文件的内容来解决此问题extern "C++".