Subject: Re: Package archive needs more stuff--here's an inventory
To: None <current-users@NetBSD.ORG, jtk@atria.com, netbsd-users@NetBSD.ORG>
From: Olaf Seibert <rhialto@mbfys.kun.nl>
List: netbsd-users
Date: 03/14/1995 11:23:40
> gcc-2.6.3.tar.gz        GNU C Compiler, 2.6.3 (i386)

I installed gcc 2.6.3 from the binary package at ftp.netbsd.org,
and with g++ I'm having trouble with template functions being
multiply defined.

/var/tmp/cc0004021.o: Definition of symbol `_split__t10DoubleList1Zi' (multiply defined)
/var/tmp/cc0004022.o: Definition of symbol `_split__t10DoubleList1Zi' (multiply defined)

Using 2.4.5 seems to work ok, but using such an old version is not
acceptable.

Since I didn't install a new linker (/usr/bin/ld is used), perhaps
it is a linker problem. Could anybody shed some light on this?

Full example follows.

Script started on Tue Mar 14 11:08:32 1995
polder:/var/tmp$ cat -n *.cc *.hpp
     1     #include "dlist.hpp"
     2  
     3  DoubleList <int> l;
     4  
     5  int func2(void);
     6  
     7  int main()
     8  {
     9      l.split();
    10      func2();
    11  }
     1  #include "dlist.hpp"
     2  
     3  extern DoubleList <int> l;
     4  
     5  int func2(void)
     6  {
     7      l.split();
     8      func2();
     9  }
     1  /************************************************************************/
     2  /*                                                                      */
     3  /*                              dlist.cpp                               */
     4  /*                                                                      */
     5  /*                              (C) 1993 M. T. Sinot                    */
     6  /*                              All rights reserved                     */
     7  /*                                                                      */
     8  /************************************************************************/
     9  
    10  // $Id$
    11  // $Log$
    12  
    13  // #pragma implementation "dlist.hpp"
    14  
    15  #ifndef _dlist_hpp_
    16  #include "dlist.hpp"
    17  #endif
    18  
    19  
    20  /*
    21   * double_list_base virtual destructor
    22   */
    23  double_list_base_node::~double_list_base_node ()
    24  {
    25  }
    26  
    27  
    28  /*
    29   * Clear all elements in generic list
    30   */
    31  void double_list_base::clear ()
    32  {
    33      while (begin)
    34      {
    35          cur = begin;
    36          begin = begin->next;
    37          delete cur;
    38      }
    39      begin = cur = end = 0;
    40  }
    41  
    42  
    43  /*
    44   * Return no of elements in list
    45   */
    46  unsigned double_list_base::size ()
    47  {
    48      unsigned n;
    49      double_list_base_node *c;
    50  
    51      for (c = begin, n = 0; c; c = c->next, n++);
    52      return n;
    53  }
    54  
    55  
    56  /*
    57   * Append element to end of list
    58   */
    59  void double_list_base::append (double_list_base_node* e)
    60  {
    61      e->prev = end;
    62      e->next = 0;
    63      if (end)
    64      {
    65          end->next = e;
    66      }
    67      else
    68      {
    69          begin = e;
    70      }
    71      end = cur = e;
    72  }
    73  
    74  
    75  /*
    76   * Insert element at current position.
    77   * If current position is NULL, append to end
    78   */
    79  void double_list_base::insert (double_list_base_node* e)
    80  {
    81      if (!cur)
    82      {
    83          append (e);
    84          return;
    85      }
    86      if (cur->prev)
    87      {
    88          cur->prev->next = e;
    89      }
    90      else
    91      {
    92          begin = e;
    93      }
    94      e->prev = cur->prev;
    95      e->next = cur;
    96      cur->prev = e;
    97      cur = e;
    98  }
    99  
   100  
   101  /*
   102   * Remove current element in list
   103   */
   104  void double_list_base::remove ()
   105  {
   106      assert (!empty ());         // List must not be empty
   107      assert (cur != 0);          // You must specify the element
   108      double_list_base_node *tmp = cur;
   109      cur = cur->next;
   110      if (tmp->prev)
   111      {
   112          tmp->prev->next = tmp->next;
   113      }
   114      else
   115      {
   116          begin = tmp->next;
   117      }
   118      if (tmp->next)
   119      {
   120          tmp->next->prev = tmp->prev;
   121      }
   122      else
   123      {
   124          end = tmp->prev;
   125      }
   126      delete tmp;
   127  }
   128  
   129  
   130  /*
   131   * Position list
   132   */
   133  void double_list_base::operator () (int x)
   134  {
   135      if (x >= 0)
   136      {
   137          for (Begin (); x && cur; x--, Next ());
   138      }
   139      else
   140      {
   141          for (End (); ++x && cur; Prev ());
   142      }
   143  }
   144  
   145  
   146  /*
   147   * Get index of current entry
   148   */
   149  int double_list_base::Index ()
   150  {
   151      if (cur)
   152      {
   153          double_list_base_node *pp;
   154          int x;
   155          for (x = 0, pp = cur->prev; pp; x++, pp = pp->prev);
   156          return x;
   157      }
   158      return -1;
   159  }
   160  
   161  
   162  /*
   163   * Split list into two pieces
   164   */
   165  void double_list_base::split (double_list_base& l)
   166  {
   167      if (cur)
   168      {
   169          // Everything from cur goes into the second list
   170          l.begin = cur;
   171          l.end = end;
   172          l.cur = 0;
   173  
   174          // Everything upto, but not including cur, stays in this
   175          end = cur->prev;
   176          cur = 0;
   177          if (!end)
   178          {
   179              begin = 0;
   180          }
   181  
   182          // Clear list ends
   183          else
   184          {
   185              end->next = l.begin->prev = 0;
   186          }
   187      }
   188  }
   189  
   190  
   191  /*
   192   * Merge two lists
   193   */
   194  void double_list_base::merge (double_list_base& l)
   195  {
   196      if (begin)
   197      {
   198          if (l.begin)
   199          {
   200              end->next = l.begin;
   201              l.begin->prev = end;
   202              end = l.end;
   203              cur = l.begin;
   204              l.fastclear ();
   205          }
   206          else
   207          {
   208              cur = 0;
   209          }
   210      }
   211      else
   212      {
   213          *this = l;
   214          cur = begin;
   215          l.fastclear ();
   216      }
   217  }
     1	/************************************************************************/
     2	/*									*/
     3	/*				dlist.hpp				*/
     4	/*									*/
     5	/*				(C) 1993 M. T. Sinot			*/
     6	/*				All rights reserved			*/
     7	/*									*/
     8	/************************************************************************/
     9	
    10	// #pragma interface
    11	
    12	// $Id$
    13	// $Log$
    14	
    15	#ifndef	_dlist_hpp_
    16	#define	_dlist_hpp_
    17	
    18	
    19	#ifndef	__ASSERT_H
    20	#include <assert.h>
    21	#endif
    22	
    23	/*
    24	 * Generic double link node base for list class
    25	 */
    26	class double_list_base;
    27	class double_list_base_node {
    28	friend class double_list_base;
    29	public:
    30	    double_list_base_node ():
    31		prev (0), next (0) {}
    32	    double_list_base_node (double_list_base_node* p,
    33				   double_list_base_node* n):
    34		prev (p), next (n) {}
    35	
    36	    virtual ~double_list_base_node ();
    37	protected:
    38	    double_list_base_node *prev, *next;
    39	};
    40	
    41	
    42	/*
    43	 * Derived template place holder for list class
    44	 */
    45	template <class ELEM>
    46	class DoubleListNode: public double_list_base_node {
    47	public:
    48	    DoubleListNode (ELEM e):
    49		head (e) {}
    50	    DoubleListNode (ELEM e, DoubleListNode* p, DoubleListNode *n):
    51		head (e), double_list_base_node (p, n) {}
    52	
    53	    ELEM head;
    54	};
    55	
    56	
    57	/*
    58	 * Generic list base class
    59	 */
    60	class double_list_base {
    61	public:
    62	    // Constructor/destructor
    63	    double_list_base ():
    64		begin (0), cur (0), end (0) {}
    65	
    66	    // List clear
    67	    void clear ();			// remove all elements
    68	    void fastclear ()			// clear list without removing elements
    69		{ begin = cur = end = 0; }
    70	
    71	    // list tests
    72	    int empty ()		// returns nonzero if list is empty
    73		{ return begin == 0; }
    74	    int operator ! ()           // returns nonzero if current pos empty
    75		{ return cur == 0; }
    76	    operator void * ()		// returns nonzero if current pos not empty
    77		{ return (cur ? this : 0); }
    78	    unsigned size ();		// return # of elements in list
    79	    int Index ();		// return current index (-1 if not valid)
    80	
    81	protected:
    82	    // append/remove
    83	    void append (double_list_base_node*); // append to end of list
    84	    void insert (double_list_base_node*); // insert before current position
    85	    void remove ();		 	// remove element
    86	
    87	    // split/merge
    88	    void split (double_list_base&);
    89	    void merge (double_list_base&);
    90	
    91	    // list positioning
    92	    void Begin ()
    93		{ cur = begin; }
    94	    void Prev ()
    95		{ if (cur) cur = cur->prev; }
    96	    void Next ()
    97		{ if (cur) cur = cur->next; }
    98	    void End ()
    99		{ cur = end; }
   100	    void operator () (int);		// position list:
   101						// positive indices look forward,
   102						// negative indices look backward
   103	
   104	    double_list_base_node *begin, *cur, *end;
   105	};
   106	
   107	
   108	/*
   109	 * Template list class
   110	 */
   111	template <class ELEM>
   112	class DoubleList: public double_list_base {
   113	public:
   114	    // constructor/destructor
   115	    DoubleList ():
   116		double_list_base () {}
   117	    DoubleList (ELEM e)
   118		{ begin = end = new DoubleListNode<ELEM> (e, 0, 0); }
   119	    ~DoubleList () {}
   120	
   121	    // list positioning
   122	    DoubleList& Begin ()
   123		{ double_list_base::Begin (); return *this; }
   124	    DoubleList& Prev ()
   125		{ double_list_base::Prev (); return *this; }
   126	    DoubleList& Next ()
   127		{ double_list_base::Next (); return *this; }
   128	    DoubleList& End ()
   129		{ double_list_base::End (); return *this; }
   130	    DoubleList& operator () (int x)
   131		{ double_list_base::operator () (x); return *this; }
   132	
   133	    // append/remove
   134	    DoubleList& append (ELEM e)	// append to end of list
   135		{ double_list_base::append (new DoubleListNode<ELEM> (e, 0, 0));
   136		  return *this; }
   137	    DoubleList& insert (ELEM e)	// insert before current position
   138		{ double_list_base::insert (new DoubleListNode<ELEM> (e, 0, 0));
   139		  return *this; }
   140	    DoubleList& remove ()		// remove current element
   141		{ double_list_base::remove (); return *this; }
   142	
   143	    // Split/merge
   144	    DoubleList  split ();		// split list in two parts; everything upto, but not 
   145						// including current position is kept in list; 
   146						// everything after it is returned. If the list
   147						// position is not valid, returns an empty list.
   148	    DoubleList& merge (DoubleList& l)   // concatenate lists; second list is emptied
   149	    	{ double_list_base::merge (l); return *this; }
   150	
   151	    // element retrieval
   152	    ELEM& Head ()
   153		{ assert (cur); return ((DoubleListNode<ELEM>*) cur)->head; }
   154	
   155	#ifdef DEBUG
   156	    // display
   157	    friend ostream& operator << (ostream&, DoubleList);
   158	#endif
   159	};
   160	
   161	
   162	/*
   163	 * Split list 
   164	 */
   165	template <class ELEM>
   166	DoubleList<ELEM> DoubleList<ELEM>::split ()
   167	{
   168	    DoubleList<ELEM> l;
   169	    double_list_base::split (l);
   170	    return l;
   171	}
   172	
   173	
   174	/****************
   175	 *
   176	 * Display functions
   177	 *
   178	 ****************/
   179	
   180	
   181	#ifdef DEBUG
   182	/*
   183	 * Send list formatted to ostream
   184	 */
   185	template <class ELEM>
   186	ostream& operator << (ostream& o, DoubleList<ELEM> l)
   187	{
   188	    int i;
   189	    o << '{';
   190	    for (i = 0, l.Begin (); l; l.Next (), i = 1)
   191	    {
   192		if (i)
   193		{
   194		    o << ", ";
   195		}
   196		o << l.Head ();
   197	    }
   198	    o << '}';
   199	    return o;
   200	}
   201	#endif
   202	
   203	
   204	/****************
   205	 *
   206	 * Search function
   207	 *
   208	 ****************/
   209	
   210	/*
   211	 * Search on key.
   212	 * For this function, operator == (ELEM, KEY) must be defined.
   213	 */
   214	template <class ELEM, class KEY>
   215	int Search (DoubleList<ELEM>& l, KEY k)
   216	{
   217	    for (l.Begin (); l; l.Next ())
   218	    {
   219		if (l.Head () == k)
   220		{
   221		    return 1;
   222		}
   223	    }
   224	    return 0;
   225	}
   226	
   227	
   228	#endif
polder:/var/tmp$ gcc -v *.cc
Reading specs from /usr/local/lib/gcc-lib/i386-unknown-netbsd1.0A/2.6.3/specs
gcc version 2.6.3
 /usr/local/lib/gcc-lib/i386-unknown-netbsd1.0A/2.6.3/cpp -lang-c++ -v -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus -D__GNUC_MINOR__=6 -Dunix -Di386 -D__NetBSD__ -D__unix__ -D__i386__ -D__NetBSD__ -D__unix -D__i386 -Asystem(unix) -Asystem(NetBSD) -Acpu(i386) -Amachine(i386) c1.cc /var/tmp/cc000402.ii
GNU CPP version 2.6.3 (80386, BSD syntax)
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/g++-include
 /usr/include/g++
 /usr/include
End of search list.
 /usr/local/lib/gcc-lib/i386-unknown-netbsd1.0A/2.6.3/cc1plus /var/tmp/cc000402.ii -quiet -dumpbase c1.cc -version -o /var/tmp/cc000402.s
GNU C++ version 2.6.3 (80386, BSD syntax) compiled by GNU C version 2.6.3.
 /usr/bin/as -o /var/tmp/cc0004021.o /var/tmp/cc000402.s
 /usr/local/lib/gcc-lib/i386-unknown-netbsd1.0A/2.6.3/cpp -lang-c++ -v -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus -D__GNUC_MINOR__=6 -Dunix -Di386 -D__NetBSD__ -D__unix__ -D__i386__ -D__NetBSD__ -D__unix -D__i386 -Asystem(unix) -Asystem(NetBSD) -Acpu(i386) -Amachine(i386) c2.cc /var/tmp/cc000402.ii
GNU CPP version 2.6.3 (80386, BSD syntax)
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/g++-include
 /usr/include/g++
 /usr/include
End of search list.
 /usr/local/lib/gcc-lib/i386-unknown-netbsd1.0A/2.6.3/cc1plus /var/tmp/cc000402.ii -quiet -dumpbase c2.cc -version -o /var/tmp/cc000402.s
GNU C++ version 2.6.3 (80386, BSD syntax) compiled by GNU C version 2.6.3.
 /usr/bin/as -o /var/tmp/cc0004022.o /var/tmp/cc000402.s
 /usr/local/lib/gcc-lib/i386-unknown-netbsd1.0A/2.6.3/cpp -lang-c++ -v -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus -D__GNUC_MINOR__=6 -Dunix -Di386 -D__NetBSD__ -D__unix__ -D__i386__ -D__NetBSD__ -D__unix -D__i386 -Asystem(unix) -Asystem(NetBSD) -Acpu(i386) -Amachine(i386) dlist.cc /var/tmp/cc000402.ii
GNU CPP version 2.6.3 (80386, BSD syntax)
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/g++-include
 /usr/include/g++
 /usr/include
End of search list.
 /usr/local/lib/gcc-lib/i386-unknown-netbsd1.0A/2.6.3/cc1plus /var/tmp/cc000402.ii -quiet -dumpbase dlist.cc -version -o /var/tmp/cc000402.s
GNU C++ version 2.6.3 (80386, BSD syntax) compiled by GNU C version 2.6.3.
 /usr/bin/as -o /var/tmp/cc0004023.o /var/tmp/cc000402.s
 /usr/bin/ld -e start -dc -dp /usr/lib/crt0.o -L/usr/local/lib -L/usr/local/lib/gcc-lib/i386-unknown-netbsd1.0A/2.6.3 -L/usr/bin -L/usr/local/lib /var/tmp/cc0004021.o /var/tmp/cc0004022.o /var/tmp/cc0004023.o -lgcc -lc -lgcc
/var/tmp/cc0004021.o: Definition of symbol `_split__t10DoubleList1Zi' (multiply defined)
/var/tmp/cc0004022.o: Definition of symbol `_split__t10DoubleList1Zi' (multiply defined)
polder:/var/tmp$ exit

Script done on Tue Mar 14 11:09:09 1995