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)