Just for completeness… If, on MAC OSX, I redefine the PATH so that the MacPorts installation is completely excluded, the g++, $ /usr/bin/g++ -v Using built-in specs. Target: i686-apple-darwin11 Configured with: /private/var/tmp/llvmgcc42/llvmgcc42-2336.11~67/src/configure --disable-checking --enable-werror --prefix=/Applications/Xcode.app/Contents/Developer/usr/llvm-gcc-4.2 --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-prefix=llvm- --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin11 --enable-llvm=/private/var/tmp/llvmgcc42/llvmgcc42-2336.11~67/dst-llvmCore/Developer/usr/local --program-prefix=i686-apple-darwin11- --host=x86_64-apple-darwin11 --target=i686-apple-darwin11 --with-gxx-include-dir=/usr/include/c++/4.2.1 Thread model: posix gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00) gives the same (linker) errors… Ciao, Angelo. Il giorno 10/nov/2012, alle ore 04:25, Michael Witten ha scritto: > 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