On Fri, 9 Nov 2012 17:55:44 -0800, Ian Lance Taylor wrote: > On Fri, Nov 9, 2012 at 12:34 PM, Angelo Graziosi wrote: > >> $ cat foo01.cc >> #include "foo.hh" >> >> MYCLASS_INSTANTIATE_TYPES >> >> $ cat foo02.cc >> #include "foo.hh" >> >> MYCLASS_INSTANTIATE_TYPES >> >> $ cat foo.hh >> >> #define MYCLASS_INSTANTIATE(g) g(int) >> >> #define MYCLASS_INSTANTIATE_BASE(type) \ >> template class MyClassBase<type>; >> >> #define MYCLASS_INSTANTIATE_TYPES \ >> MYCLASS_INSTANTIATE(MYCLASS_INSTANTIATE_BASE) >> >> Now what happens is this: >> >> Building on *** MAC OSX *** with gcc45, gcc46, gcc47 installed by means of MacPorts, fails as >> >> $ g++ foomain.o foo01.o foo02.o -o foo.out >> duplicate symbol MyClassBase<int>::ClassWrapper::ClassWrapper() in: >> foo01.o >> foo02.o >> duplicate symbol MyClassBase<int>::ClassWrapper::ClassWrapper() in: >> foo01.o >> foo02.o >> ld: 2 duplicate symbols for architecture x86_64 >> collect2: error: ld returned 1 exit status >> >> instead it builds (on MAC OSX) using clang++, > > This question is not appropriate for the mailing list gcc@xxxxxxxxxxx. > It would be appropriate for gcc-help@xxxxxxxxxxx. Please take any > followups to gcc-help. Thanks. > > Instantiating a template creates all the instantiations in that > compilation unit. There is no reason to instantiate a template in > more than one compilation unit. The implementation that GCC uses does > not permit you to do that. I don't know what LLVM does. According to C++11.14.7, paragraph 5: For a given template and a given set of template-arguments, -- an explicit instantiation definition shall appear at most once in a program, ... An implementation is not required to diagnose a violation of this rule. So, it's not allowed for *any* implementation, though an implementation need not diagnose it. However, Ian, you're missing the most interesting bit from Angelo's email, namely that a GCC toolchain doesn't always have a problem with multiple instantiations: >> It also builds on Cygwin with gcc-4.5.3 and gcc-4.8 snapshot. >> >> It builds on GNU/Linux (K)Ubuntu with gcc-4.6.3 Indeed, his code compiles without error on my x86/Linux machine, using g++ 4.7.2 with the options `-std=c++03 -pedantic -Wall -Wextra -Werror'. There wasn't one peep from my toolchain. Anyway, I would have imagined that this error would only be caught by the linker, and that is precisely what happens according to Angelo: >> ld: 2 duplicate symbols for architecture x86_64 Yet, clang++ on the same system has no trouble: >> instead it builds (on MAC OSX) using clang++, How does that make sense? Is a different linker being used with the GCC toolchain? If so, which one? GNU ld doesn't support Mach-O, and even if it did, GNU ld doesn't appear to mind the error on at least a few other systems. Some insight on this aspect would be nice. Sincerely, Michael Witten