g++ fails mysteriously only if a .h is in a certain directory

c++, g++, macos, xcode

Solution

G++ may well indeed be assuming that everything in /usr/include is C. Try compiling your code with -E and studying the line markers in the preprocessor output:

g++ -E test.cpp | grep '^#'

You'll likely see things like

# 1 "/usr/include/gfc2/macros.h" 1 3 4

The `4` is the preprocessor hinting to G++ that it should wrap everything in `extern "C"`, on the supposition that your platform's ancient header files in /usr/include predate C++. See Preprocessor Output in the CPP manual.

These days G++ mostly ignores this hint, because most platforms' C headers are no longer ancient. See the `NO_IMPLICIT_EXTERN_C` target macro in the GCC Internals manual. But it may be that this old version of Xcode has GCC configured without `NO_IMPLICIT_EXTERN_C` and thus is listening to the preprocessor's hint. (This is set when GCC itself is built -- I don't think there's a command-line switch to override it.)

You may be able to work around this by wrapping the contents of your header file in `extern "C++"`.

Problem

I'm experiencing an extremely weird problem in a fresh OSX 10.4.11 + Xcode 2.5 installation. I've reduced it to a minimal test case. Here's test.cpp: ``` #include "macros.h" int main (void) { return 1; } ``` And here's 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__ ``` This compiles and works just fine if both files are in the same directory. HOWEVER, if I put macros.h in /usr/include/gfc2 (it's part of a custom library I use) and change the #include in test.cpp, compilation fails with this error : ``` /usr/include/gfc2/macros.h:4: error: template with C linkage ``` I researched that error and most of the comments point to a "dangling extern C", which doesn't seem to be the case at all. I'm at a complete loss here. Is g++ for some reason assuming everything in `/usr/include/gfc2` is C even though it's included from a .cpp file that doesn't say extern "C" anywhere? Any ideas? EDIT : It does compile if I use the full path in the `#include`, ie `#include "/usr/include/gfc2/macros.h"` EDIT2 : It's not including the wrong header. I've verified this using `cpp`, `g++ -E`, and renaming `macros.h` to `foobarmacros.h`

Original source

Related problems