Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Mar 1995 12:30:59 -0800
From:      "Justin T. Gibbs" <gibbs@estienne.CS.Berkeley.EDU>
To:        nate@FreeBSD.org
Cc:        current@FreeBSD.org
Subject:   Patch for gcc
Message-ID:  <199503172031.MAA16609@estienne.cs.berkeley.edu>

next in thread | raw e-mail | index | archive | help

On of the professors I work for pointed this out to me:

Begin Forwarded Message
-----------------------


Gcc v2.6.3 currently has a problem with templates.  Specifically, with
default switches, template functions get EXTERNAL linkage in each file
in which they occur, causing multiple definition errors during
linking.  The enclosed patch (from gnu.g++.bug) appears to solve the
problem (I enclose the accompanying message as well).  It would be
nice to install this in /usr/local/bin.

Paul

- --------------------------------------------------
Article: 14433 of gnu.g++.bug
From: rjl@iassf.easams.COM.AU (Rohan LENARD)
Newsgroups: gnu.g++.bug
Subject: Re: Multiple Method Definitions in Templates
Date: 8 Mar 1995 17:23:44 -0500
Organization: GNUs Not Usenet
Lines: 136
Sender: daemon@cis.ohio-state.edu
Approved: bug-g++@prep.ai.mit.edu
Distribution: gnu
Message-ID: <0jLUto3_3gX_0Ak1g0@iassf.easams.com.au>
References: <10330.794622376@N2.SP.CS.CMU.EDU>

Hi there,

Thanks for the bug report.

I forgot to supply the patch for this problem in my previous mail. Here it is -

Regards,
	Rohan
- ------------------------------------------------------------------------
(Thanks to Jason Merrill at cygnus support).
This patch fixes the multiply defined template functions bug
which was introduced in 2.6.1.

Jason

*** ../../gcc-2.6.3/cp/pt.c     Mon Nov 14 23:34:29 1994
- --- pt.c        Mon Dec 12 21:10:06 1994
***************
*** 2302,2307 ****
- --- 2302,2311 ----
        else if (! flag_implicit_templates)
        DECIDE (0);
  
+       if (i->interface == 1)
+       /* OK, it was an implicit instantiation.  */
+       TREE_PUBLIC (t) = 0;
+ 
        /* If it's a method, let the class type decide it.
         @@ What if the method template is in a separate file?
         Maybe both file contexts should be taken into account?
- ------------------------------------------------------------------------
Excerpts from BugReport.Gnu: 7-Mar-95 Multiple Method Definitions..
Peter_Stephan@n2.sp.cs.c (2274)


> I encountered a situation which I believe is a bug.  It occurs
> in version 2.6.3 of g++ on both DEC Alphas running OSF1 v2.0 and 
> SUN4s running SunOS v4.1.3.

> The situation occurs when using a C++ template in two or more 
> modules which are ultimately linked together and is similar to another
> bug report that I have just submitted.  As seen in the brief examples 
> below, I have defined a templated class, dv, with a method print.  I have
> also defined a version of the print method specifically for instantiations
> of this template with <char>.  The linker identifies the print method as 
> being multiply defined.  If there is only one module to this system, it 
> seems to work fine.  When the example code given is compiled and linked, 
> the following output results:

> pheasant <278> g++ -fexternal-templates -c prog1.C -o prog1.o
> pheasant <279> g++ -fexternal-templates -c prog2.C -o prog2.o
> pheasant <280> g++ -fexternal-templates prog1.o prog2.o -o prog
> ld: prog2.o: _print__t2dv1Zc: multiply defined
> collect2: ld returned 2 exit status

> This problem was not exhibited when using g++ version 2.5.8 on the
> same platforms without the #pragma and -fexternal-templates stuff.

> Any information would be appreciated.

> Thank you,

> Peter
> ---
> Peter Stephan                CMU School of Computer Science
> pstephan@cs.cmu.edu          Wean Hall Room 7106
> Research Programmer          (412) 268-7663


> /***** prog.h ******/
> #pragma interface
> #include <iostream.h>

> template <class TYPE> class dv {

> public:

>   dv(TYPE d) {
>     data = d;
>     }

>   ~dv() {}

>   void print();

> private:

>   TYPE data;
> };

> template <class TYPE> void dv<TYPE>::print() {
>   cout << "Data =  " << "." << data << "\n";
>   return;
>   }

> void dv<char>::print() {
>   cout << "Char =  " << data << ".\n";
>   return;
>   }
> /***** end of prog.h ******/

> /***** prog1.C *****/
> #pragma implementation "prog.h"
> #include "prog.h"

> extern void another_routine();

> main() {

>   dv<int>  vi(8);
>   dv<char> vc('z');

>   vi.print();
>   vc.print();

>   another_routine();
>   cout << "Normal program termination." << endl;
>   }
> /***** end of prog1.C *****/

> /***** prog2.C *****/
> #include "prog.h"

> void another_routine() {

>   dv<int>  vi(1);

>   vi.print();

>   cout << "Finished in another_routine." << endl;
>   }
> /***** end of prog2.C *****/







------- End of Forwarded Message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199503172031.MAA16609>