Delivered-To: listarch-cygwin AT sourceware DOT cygnus DOT com Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm Sender: cygwin-owner AT sourceware DOT cygnus DOT com Delivered-To: mailing list cygwin AT sourceware DOT cygnus DOT com From: Graham Dumpleton Message-Id: <199902160247.NAA20369@baldric.pad.otc.com.au> Subject: Re: B20: make confused with //a style drive specifiers To: khan AT xraylith DOT wisc DOT EDU (Mumit Khan) Date: Tue, 16 Feb 1999 13:47:19 +1100 (EST) Cc: Graham DOT Dumpleton AT ra DOT pad DOT otc DOT com DOT au, cygwin AT sourceware DOT cygnus DOT com In-Reply-To: <199902152346.RAA23570@modi.xraylith.wisc.edu> from "Mumit Khan" at Feb 15, 99 05:46:18 pm X-Mailer: ELM [version 2.4 PL24] Content-Type: text > Hi Graham, > > Could you possibly put together a test case so I can try and get a fix in > before egcs-1.1.2 is released? What you see sounds like a bug in emitting > .linkonce directive (somewhat like "weak" symbols in ELF, but done at the > section level instead of symbol level) for certain inlines. > > In the meantime, I'll download the latest release and try it out. > > Regards, > Mumit Worked out a way of duplicating the problem with a small example. This code compiles and links fine with Cygnus GNUPRO C++ 98r1 on Solaris 2.5.1. What I am doing here has also worked when I have built OSE on Linux RH5.2, which I think was using EGCS. There are a couple of strange things to note about how I handle templates. The first is that template implementations would never usually be seen when compiling non main object file. Further, for a template which is totally inline as is the case here, the #pragma interface/implementation are only used when builing main object file. That is, for any non main object file, inlines of template if they are expanded should only have local/weak scope. When building main object, template is implemented with extern linkage. Normally, this should override weak linkage in non main object files, but this isn't what is happening here, as non main object symbols are not local/weak. <<<< h1.hh >>>> #if defined(EXPAND_TEMPLATES) #pragma implementation "h1.hh" #pragma interface "h1.hh" #endif template class ONE { public: ONE(void* anIter) { anIter = 0; } }; <<<< o1.cc >>>> #include "h1.hh" void func1() { ONE iter((void*)0); } <<<< m1.cc >>>> #define EXPAND_TEMPLATES 1 #include "h1.hh" main() { ONE iter((void*)0); return 0; } Commands to run ar: g++ -c o1.cc g++ -c -fexternal-templates m1.cc g++ m1.o o1.o Actual log of this is as follows. Note that when building OSE, you don't usually see the pragma warning. I have never been able to work out what it is about how I do this in OSE that results in the compiler not generating the warning even though I am doing the exact same thing. bash-2.02$ g++ -c o1.cc bash-2.02$ g++ -c -fexternal-templates m1.cc In file included from m1.cc:3: h1.hh:2: warning: `#pragma implementation' for "h1.hh" appears after its #include bash-2.2$ g++ m1.o o1.o o1.o(.text$__t3ONE1ZiPv+0x0):o1.cc: multiple definition of `ONE::ONE(void *)' m1.o(.text+0x0):m1.cc: first defined here collect2: ld returned 1 exit status Note that doing an nm on o1.o reveals: bash-2.02$ nm o1.o | c++filt 00000000 b .bss 00000000 d .data 00000000 t .text 00000000 t .ONE::text$(void *) 00000000 t ___gnu_compiled_cplusplus 00000000 T ONE::_(void *) 00000000 T _func1(void) 00000000 t gcc2_compiled. Ie., "ONE::_(void *)" has "T" and not "t". I am presuming that "t" means local/weak. An nm on m1.o produces: bash-2.02$ nm m1.o | c++filt 00000000 b .bss 00000000 d .data 00000000 t .text 00000000 t ___gnu_compiled_cplusplus U ___main 00000000 T ONE::_(void *) 00000014 T _main 00000000 t gcc2_compiled. If you need to know more, let me know. -- Graham Dumpleton (grahamd AT nms DOT otc DOT com DOT au)