C++ g++;仅当.h位于某个目录中时才会神秘地失败
我在新的OSX 10.4.11+Xcode 2.5安装中遇到了一个非常奇怪的问题。我已经把它简化为一个最小的测试用例。下面是test.cpp:C++ g++;仅当.h位于某个目录中时才会神秘地失败,c++,xcode,macos,g++,C++,Xcode,Macos,G++,我在新的OSX 10.4.11+Xcode 2.5安装中遇到了一个非常奇怪的问题。我已经把它简化为一个最小的测试用例。下面是test.cpp: #include "macros.h" int main (void) { return 1; } 这是宏。h: #ifndef __JUST_TESTING__ #define __JUST_TESTING__ template<typename T> void swap (T& pT1, T& pT2) {
#include "macros.h"
int main (void)
{
return 1;
}
这是宏。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__
我研究了这个错误,大多数评论都指向一个“悬而未决的外部C”,这似乎根本不是事实
我在这里完全不知所措。出于某种原因,g++是否假设/usr/include/gfc2
中的所有内容都是C,即使它是从一个在任何地方都没有显示extern“C”的.cpp文件中包含的
有什么想法吗
编辑:如果我在#include
中使用完整路径,即#include”/usr/include/gfc2/macros.h“
EDIT2:它没有包含错误的标题。我已经使用
cpp
,g++-E
,并将macros.h
重命名为foobarmacros.h
验证了这一点。嗯,它看起来真的很奇怪
XCode如何调用g++?
我认为g++不会因为一个包含文件在不同的目录中就自然而然地决定它具有C链接。你有没有试着手工编译你的项目?
尝试“g++main.cpp-I/usr/include/gfc2/”。如果这解决了你的问题,那就不是g++。也许XCode会预编译头?您是否尝试过根本不更改test.cpp文件,而是在编译时说:
-I/usr/include/gfc2/
这是在黑暗中拍摄的,但是在
/usr/include
下或您的GCC安装中是否有另一个名为macros.h
的文件?GCC有一个用于包装标题的工具,名为,这可能是问题的原因
要消除包含路径中任何其他宏.h
与宏.h
之间的歧义,可以做的一件事是将其作为gfc2/macros.h
包含。这样,编译器将在include路径中的每个目录中搜索名为gfc2
的子目录,其中包含名为macros.h
的文件,从而减少冲突的可能性。它还可以防止您将/usr/include/gfc2
添加到include路径
顺便说一句,#include“file.h”
首先搜索当前目录。要跳过该选项并直接转到包含路径,请使用#include
:
#包括
#包括
另一种方法是选择一个更可能是唯一的文件名,如
gfc2macros.h
您可以看到g++在哪里查找带有详细标志的包含:
g++ -v -o test test.cpp
这将只运行预处理器,并显示文件中实际包含和编译的内容:
g++ -E test.cpp | less
如果包含了错误的文件(或者像bk1e建议的那样,您的头被另一个文件包装),您可以通过该输出找到答案。G++可能确实假设/usr/include中的所有内容都是C。请尝试使用-E编译代码,并研究预处理器输出中的行标记:
g++ -E test.cpp | grep '^#'
你可能会看到这样的事情
# 1 "/usr/include/gfc2/macros.h" 1 3 4
<代码> 4 是预处理器暗示g++,它应该在
NO\u IMPLICIT\u EXTERN\u C
target宏。但可能是这个旧版本的Xcode配置了GCC,没有NO\u IMPLICIT\u EXTERN\u C
,因此正在侦听预处理器的提示。(这是在构建GCC本身时设置的——我认为没有命令行开关来覆盖它。)
您可以在包中使用包文件中的内容,在代码>外部“C++”<代码> > < /P> < P>我在编译一个C++项目时也遇到了这个问题,我们通常在10.5和10.6(XCODE 3 +)上构建一个XPoC 2.5的10.4 PPC机。看起来,预处理器处理添加到gcc include路径的任何内容时,都会使用“-isystem”作为“extern C”。将'-isystem'更改为'-I'解决了问题。
这是一个毫无希望、毫无信息的万对一的暗箱操作,但请尝试从目录名中删除“c”。)试着在这里发布“set | grep-i include”的结果。@datageist-谢谢,但这没有什么区别。奇怪的是,如果我使用它的完整路径包含它,它会编译。嗯……如果它在使用完整路径时起作用,这可能意味着它在include路径[实际上是一个c头]中拾取了一些其他的“macros.h”。您可以尝试重新编译(对于open),以准确地观察它正在编译的宏.h。可能还有另一个正在接收。编辑:也可能有另一个包含macros.h的标题,当它位于库目录中时,您的版本将被选择,而不是预期的版本。尝试将其重命名为类似于我的_macros.h,看看是否有帮助。事实上,我使用的是命令行编译器,更准确地说是g++-o test test.cpp。您是否尝试将“macros.h”重命名为“macros.hpp”?谢谢!这是可行的,但我把它归入“变通办法”类别。我宁愿修复根本原因,因为这段代码一直在Linux、Mac和Windows中工作,所以我很确定这是一个特定安装的问题。(为了完整性,这项工作的原因是,标题现在来自此选项中命名的普通目录,而不是从特殊的内置/usr/include
。由于标头不是来自特殊目录,预处理器不会在其行标记上放置4
标志,因此G++不会试图将其包装在extern“C”
中。(有关这些标志的解释,请参见我上面的回答。)我也考虑过这一点,但cpp的输出确认g++正在拉取正确的宏.h(除了错误消息包含我的文件的完整路径这一事实之外)。/usr/include中没有其他宏.h。您是运行了cpp
还是运行了g++
g++ -E test.cpp | grep '^#'
# 1 "/usr/include/gfc2/macros.h" 1 3 4