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