This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: What is wrong in this code?


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@gcc.gnu.org.
> It would be appropriate for gcc-help@gcc.gnu.org.  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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]