http://gcc.gnu.org/bugzilla/show_bug.cgi?id=2316
--- Comment #51 from Harald van Dijk <harald at gigawatt dot nl> --- (In reply to Marc Glisse from comment #49) > Fixing this particular issue should > not be too hard, there must be a place in the compiler that merges a number > of properties from the early declaration into the definition, and we need to > add extern "C" to that list. That does indeed seem simple enough. duplicate_decls can change the type pretty much the same way it can change the name's linkage (except it cannot simply modify the old type; it does have to build a new one, but it can set the new type in the existing declaration), and can do so at the same location. It seems like the right place to do it, since the inheritance of the type's linkage works pretty much the same way as the inheritance of the name's linkage. Note that a consequence of this is that a function declaration that uses a typedef may not be compatible with the typedef (I think): extern "C" { void f(); } typedef void t(); t f, *g = f; // valid redeclaration of f, invalid initialisation of g extern "C" t f; // invalid redeclaration of f extern "C++" t f; // invalid redeclaration of f Linkage conflicts with built-in declarations of functions are also a bit of a problem: implementing this as described makes GCC fail to compile, because of conflicts with built-in functions. The implicit declarations of built-in functions have types with C++ linkage. A simple example: extern "C" { int (&myputs)(const char *) = __builtin_puts; } test.cc:1:44: error: invalid initialization of reference of type ‘int (&)(const char*) extern "C"’ from expression of type ‘int(const char*)’ extern "C" { int (&myputs)(const char *) = __builtin_puts; } ^ So the same logic to change the a redeclaration's type would need to be applied to built-in function declarations as well. (I may well continue working on this, but if I do, I will only do so occasionally and will likely not be able to send anything meaningful or useful for a long time.)