Topic: Strange Behaviour of g++
Author: papanik@crypt10.cs.uni-sb.de (Thomas Papanikolaou)
Date: 25 Nov 1994 17:23:44 GMT Raw View
Dear C++ Users,
I was confronted with a peculiar problem concerning the compilation
of templates; I am not sure if this is a bug, so I would like to ask
the following:
SITUATION
A template class 'vector' defined
1) in vector1.h; the implementations of the constructors/member
functions are IN the class definition.
2) in vector2.h; the implementations of the constructors/member
functions are AFTER the class definition in the
SAME include file.
A file 'f.h' defining a function 'f' with one vector argument 'v'
f(v) returns the 'size' of 'v'. 'f.c' contains the implementation
of 'f'.
A file 'testf.c' which includes 'f.h' and calls 'f'
COMPILATION 1 (note that vector1.h is included)
c++ -c f.c
c++ -g testf.c f.o -o testf
Everything works fine for both c++ in {g++-2.6.2, cfront-3.01}
COMPILATION 2 (note that vector2.h is included)
c++ -c -DVEC2 f.c
c++ -g -DVEC2 testf.c f.o -o testf
Everything works fine cfront-3.01. g++-2.6.2 breaks compiling with
ld: f.o: _size__t6vector1Zi: multiply defined
ld: f.o: __$_t6vector1Zi: multiply defined
ld: f.o: ___t6vector1Zi: multiply defined
ld: f.o: ___t6vector1Zii: multiply defined
ld: f.o: _capacity__t6vector1Zi: multiply defined
collect2: ld returned 2 exit status
QUESTION
Why does the second compilation fail? Is it a bug or a feature?
Which behaviour is correct?
Thank you in advance,
Thomas Papanikolaou
PS Please answer per email; I will send a summary.
------------- included files ------------------------------------
:::::::::::::::
file: vector1.h
:::::::::::::::
#ifndef VECTOR_H
#define VECTOR_H
#define nil 0
template <class T> class vector
{
protected :
T *data ;
int length ;
int allocated ;
public :
vector () // create empty vector
{
length = 0 ;
allocated = 0 ;
data = nil ;
}
vector ( const int i ) // create vector of capacity "i"
{
length = 0 ;
allocated = i ;
data = nil ;
if ( i > 0 )
data = new T [ i ] ;
}
~vector() // destruct vector
{
if ( allocated ) { delete[] data ; }
data = nil ;
length = 0 ;
allocated = 0 ;
}
int capacity ( )
{
return allocated ;
}
int size ( )
{
return length ;
}
};
#endif
:::::::::::::::
file: vector2.h
:::::::::::::::
#ifndef VECTOR_H
#define VECTOR_H
#define nil 0
template <class T> class vector
{
protected :
T *data ;
int length ;
int allocated ;
public :
vector ( ) ;
vector ( const int i ) ;
~vector ( ) ;
int capacity ( ) ; // return the vector's capacity
int size ( ) ; // return the vector's size
int set_size ( int len ) ; // set the vector's size to len
} ;
template <class T> vector<T>::vector ()
// create empty vector
{
length = 0 ;
allocated = 0 ;
data = nil ;
}
template <class T> vector<T>::vector ( const int i )
// create vector of cap. "i"
{
length = 0 ;
allocated = i ;
data = nil ;
if ( i > 0 )
data = new T [ i ] ;
}
template <class T> vector< T >::~vector()
{
if ( allocated ) { delete[] data ; }
data = nil ;
length = 0 ;
allocated = 0 ;
}
template <class T> int vector< T >::capacity ( )
{
return allocated ;
}
template <class T> int vector< T >::size ( )
{
return length ;
}
#endif
:::::::::::
file: f.h
:::::::::::
#ifdef VEC2
#include "vector2.h"
#else
#include "vector1.h"
#endif
int f ( vector< int > v ) ;
:::::::::::
file: f.c
:::::::::::
#include "f.h"
int f ( vector< int > v )
{
return v.size() ;
}
:::::::::::::
file: testf.c
:::::::::::::
#include <stream.h>
#include "f.h"
main ( )
{
vector< int > w(10);
f ( w ) ;
cout << w.capacity( ) << "\n" << flush;
}
--
Thomas Papanikolaou +49 681 302-4166 (office)
Max - Braun 1 +49 681 684430 (home)
D-66123 Saarbruecken papanik@cs.uni-sb.de
--
Thomas Papanikolaou +49 681 302-4166 (office)
Max - Braun 1 +49 681 684430 (home)