This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: What is wrong in this code?
- From: Michael Witten <mfwitten at gmail dot com>
- To: Ian Lance Taylor <iant at google dot com>
- Cc: Angelo Graziosi <graziosi dot angelo at gmail dot com>, gcc-help at gcc dot gnu dot org
- Date: Sat, 10 Nov 2012 03:25:57 -0000
- Subject: Re: What is wrong in this code?
- References: <5107E401-61C5-43AE-9272-FCD4D133178E@gmail.com> <CAKOQZ8wWwoq5ZE5a-dzXTmqhc-O_1+ZLSbZSYy=cnRUriU=gdQ@mail.gmail.com>
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