public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: What is wrong in this code?
       [not found] ` <CAKOQZ8wWwoq5ZE5a-dzXTmqhc-O_1+ZLSbZSYy=cnRUriU=gdQ@mail.gmail.com>
@ 2012-11-10  3:38   ` Michael Witten
  2012-11-10  8:52     ` Angelo Graziosi
  2012-11-10 19:48     ` Ian Lance Taylor
  0 siblings, 2 replies; 3+ messages in thread
From: Michael Witten @ 2012-11-10  3:38 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: Angelo Graziosi, gcc-help

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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: What is wrong in this code?
  2012-11-10  3:38   ` What is wrong in this code? Michael Witten
@ 2012-11-10  8:52     ` Angelo Graziosi
  2012-11-10 19:48     ` Ian Lance Taylor
  1 sibling, 0 replies; 3+ messages in thread
From: Angelo Graziosi @ 2012-11-10  8:52 UTC (permalink / raw)
  To: Michael Witten; +Cc: Ian Lance Taylor, gcc-help

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@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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: What is wrong in this code?
  2012-11-10  3:38   ` What is wrong in this code? Michael Witten
  2012-11-10  8:52     ` Angelo Graziosi
@ 2012-11-10 19:48     ` Ian Lance Taylor
  1 sibling, 0 replies; 3+ messages in thread
From: Ian Lance Taylor @ 2012-11-10 19:48 UTC (permalink / raw)
  To: Michael Witten; +Cc: Angelo Graziosi, gcc-help

On Fri, Nov 9, 2012 at 7:25 PM, Michael Witten <mfwitten@gmail.com> wrote:
>
> 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:

...

> 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.

GCC does not come with a linker.  There are two different linkers in
use on GNU/Linux: GNU ld and gold.  Other systems, such as MacOS, have
other linkers.  Different linkers can have different behaviours.

Probably more important here, though, is how GCC marks the
instantiated template.  If it marks it as weak in the sense used on
ELF or as COMDAT in the sense used on Windows, then multiple
instantiations will be permitted--the linker will discard later ones.
I haven't looked into the details here to see what GCC is actually
doing.  Since a correct program can only have a single explicit
instantiation, it doesn't matter too much.

Ian

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-11-10 19:48 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <5107E401-61C5-43AE-9272-FCD4D133178E@gmail.com>
     [not found] ` <CAKOQZ8wWwoq5ZE5a-dzXTmqhc-O_1+ZLSbZSYy=cnRUriU=gdQ@mail.gmail.com>
2012-11-10  3:38   ` What is wrong in this code? Michael Witten
2012-11-10  8:52     ` Angelo Graziosi
2012-11-10 19:48     ` Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).