From: paulr@hubble.ccsf.caltech.edu (Paul Ray)
Subject: Link error when using templates
Organization: California Institute of Technology, Pasadena
Distribution: gnu
Date: Wed, 19 Aug 1992 22:16:17 GMT

Here is a program that I wrote to try to use templates.
I am a novice C++ programmer, so it may be buggy.
It fails in the link step with a very odd undefined symbol.
If this is a programming error, then I think the compiler should
have told me, not the linker.

-- Paul

Here is the compile:

hubble : 724>g++ -v oink.cc -lg++
Reading specs from /usr/local/gnu/lib/gcc-lib/sun4/2.2.2/specs
gcc version 2.2.2
 /usr/local/gnu/lib/gcc-lib/sun4/2.2.2/cpp -lang-c++ -v -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__sparc -D__sun -D__unix oink.cc /usr/tmp/cca15613.i
GNU CPP version 2.2.2 (sparc)
 /usr/local/gnu/lib/gcc-lib/sun4/2.2.2/cc1plus /usr/tmp/cca15613.i -quiet -dumpbase oink.cc -version -o /usr/tmp/cca15613.s
GNU C++ version 2.2.2 (sparc) compiled by CC.
 as -o oink.o /usr/tmp/cca15613.s
 /usr/local/gnu/lib/gcc-lib/sun4/2.2.2/ld -e start -dc -dp /lib/crt0.o -L/usr/local/gnu/lib/gcc-lib/sun4/2.2.2 -L/usr/local/gnu/lib oink.o -lg++ -lg++ -lgcc -lc -lgcc
ld: Undefined symbol 
   ___apl__FGt6Series1ZfT0 
collect: /usr/bin/ld returned 2 exit status

Here is the program:

#include <iostream.h>
#include <new.h>
#include <stdlib.h>

void mem_error()
{
    cerr << "operator new failed : Out of memory on free store.\n";
    exit(721);
}

typedef struct { float re, im; } fcomplex;

enum ByteOrder {VaxOrder, SunOrder};

enum BoxMode {BoxDouble, BoxSingle, BoxFit, BoxSmart};

/* Declaration of the Series class */
/* Series are simple vectors that hold a variety of numeric data types */
template<class T>
class Series {
    ByteOrder Order;
    long Length;
    long LowIndex, HighIndex;
    float Bias, Scale;
    T *Data;

    friend Series operator+=(Series a, Series b);
public:
    Series(long low, long high);
    ~Series();
};

template<class T>
Series<T>::Series(long low, long high) 
{
    register long i;

// Initialize the members of the class
    Length = high-low+1;
    LowIndex = low;
    HighIndex = high;
    Bias = 0.0f;
    Scale = 1.0f;
#ifdef VAX_ORDER
    Order = VaxOrder;
#else
    Order = SunOrder;
#endif

    Data = new T[Length];
    Data -= LowIndex;
    for (i=LowIndex; i<=HighIndex; i++)
	Data[i] = (T)0;
    return;
}

/* Destructor for a Series */
template<class T>
Series<T>::~Series()
{
    Data += LowIndex;
    delete[] Data;
    return;
}

template<class T>
Series<T> operator+=(Series<T> a, Series<T> b) 
{
    register long i;
    if ((a.LowIndex != b.LowIndex) || (a.HighIndex != b.HighIndex)) {
	fprintf(stderr,"Error: Series operator+= : Series Range Error!\n");
	exit(54);
    }
    for (i=a.LowIndex; i<=a.HighIndex; i++)
	a.Data[i] += b.Data[i];
    return(a);
}


int main(int argc, char *argv[])
{
    set_new_handler(&mem_error);

    Series<float> timeseries(0,1023);
    Series<float> time2(0,1023);

    time2 += timeseries;

    cout << "Hello, World\n";

    exit(0);
}
-- 
Paul S. Ray              Internet: paulr@caltech.edu
206-49 Caltech           Internet: ray_p@caltech.edu
Pasadena, CA 91125       Internet: paulr@delilah.ccsf.caltech.edu
(818) 356-2911           Bitnet  : paulr@caltech.bitnet

Newsgroups: gnu.g++.bug