statics inside virtual members of template classes
Christian Millour
chris161@club-internet.fr
Fri Sep 26 14:59:00 GMT 1997
static inside virtual members of non-template classes are OK, but
statics inside virtual members of template classes may give rise to
link error (multiple definitions).
I get the problem with 970917 but I strongly suspect it is still
present in later snapshots. Otherwise, please pardon me.
bash$ e++ -v
Reading specs from /home/chris/EGCS/local-970917/lib/gcc-lib/i586-pc-linux-gnulibc1/egcs-2.90.08/specs
gcc version egcs-2.90.08 970917 (gcc2-970802 experimental)
bash$ e++ xdef.cc xdef1.cc xdef2.cc -o xdef
bash$ xdef
&x1() 0x806099c
&x2() 0x806099c
bash$ e++ -DTEMPLATES xdef.cc xdef1.cc xdef2.cc -o xdef
/tmp/cca012313.o(.bss+0x0): multiple definition of `_Q2t3Foo1Zi13x__t3Bar1Zi.2.my_x'
/tmp/cca012312.o(.bss+0x0): first defined here
/tmp/cca012313.o(.bss+0x4): multiple definition of `_Q2t3Foo1Zi13x__t3Foo1Zi.2.my_x'
/tmp/cca012312.o(.bss+0x4): first defined here
collect2: ld returned 1 exit status
bash$
This one took me some time to isolate (how comes the mangled symbols
are not understood by c++filt ? ).
Sources are in the following shar archive.
Regards,
------------------------------------------------------------------------------
#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1997-09-26 23:30 MET DST by <chris@riva>.
# Source directory was `/home/chris/EGCS/tests'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 748 -rw-r--r-- xdef.hh
# 199 -rw-r--r-- xdef.cc
# 69 -rw-r--r-- xdef1.cc
# 69 -rw-r--r-- xdef2.cc
#
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
shar_touch=touch
else
shar_touch=:
echo
echo 'WARNING: not restoring timestamps. Consider getting and'
echo "installing GNU \`touch', distributed in GNU File Utilities..."
echo
fi
rm -f 1231235999 $$.touch
#
# ============= xdef.hh ==============
if test -f 'xdef.hh' && test X"$1" != X"-c"; then
echo 'x - skipping xdef.hh (file already exists)'
else
echo 'x - extracting xdef.hh (text)'
sed 's/^X//' << 'SHAR_EOF' > 'xdef.hh' &&
#ifndef xdef_H
#define xdef_H
X
#ifdef TEMPLATES
X
template <class T>
struct Foo {
X virtual ~Foo() {}
X virtual int const & x() { static int my_x; return my_x; }
};
X
template <class T>
struct Bar : public Foo<T> {
X virtual int const & x() { static int my_x; return my_x; }
};
X
template <class T>
struct Qux : public Bar<T> {
X virtual int const & x() { static int my_x; return my_x; }
};
X
typedef Qux<int> Thingy;
X
#else
X
struct Foo {
X virtual ~Foo() {}
X virtual int const & x() { static int my_x; return my_x; }
};
X
struct Bar : public Foo {
X virtual int const & x() { static int my_x; return my_x; }
};
X
struct Qux : public Bar {
X virtual int const & x() { static int my_x; return my_x; }
};
X
typedef Qux Thingy;
X
#endif
X
#endif /* xdef_H */
SHAR_EOF
$shar_touch -am 0926232797 'xdef.hh' &&
chmod 0644 'xdef.hh' ||
echo 'restore of xdef.hh failed'
shar_count="`wc -c < 'xdef.hh'`"
test 748 -eq "$shar_count" ||
echo "xdef.hh: original size 748, current size $shar_count"
fi
# ============= xdef.cc ==============
if test -f 'xdef.cc' && test X"$1" != X"-c"; then
echo 'x - skipping xdef.cc (file already exists)'
else
echo 'x - extracting xdef.cc (text)'
sed 's/^X//' << 'SHAR_EOF' > 'xdef.cc' &&
#include <iostream.h>
#include <cassert>
X
int const & x1();
int const & x2();
X
#define DUMP(X) cout << #X << " " << X << endl
X
int
main ()
{
X DUMP(&x1());
X DUMP(&x2());
X assert(&x1() == &x2());
}
SHAR_EOF
$shar_touch -am 0926232897 'xdef.cc' &&
chmod 0644 'xdef.cc' ||
echo 'restore of xdef.cc failed'
shar_count="`wc -c < 'xdef.cc'`"
test 199 -eq "$shar_count" ||
echo "xdef.cc: original size 199, current size $shar_count"
fi
# ============= xdef1.cc ==============
if test -f 'xdef1.cc' && test X"$1" != X"-c"; then
echo 'x - skipping xdef1.cc (file already exists)'
else
echo 'x - extracting xdef1.cc (text)'
sed 's/^X//' << 'SHAR_EOF' > 'xdef1.cc' &&
#include "xdef.hh"
X
int const &
x1()
{
X Thingy q;
X return q.x();
}
SHAR_EOF
$shar_touch -am 0926232797 'xdef1.cc' &&
chmod 0644 'xdef1.cc' ||
echo 'restore of xdef1.cc failed'
shar_count="`wc -c < 'xdef1.cc'`"
test 69 -eq "$shar_count" ||
echo "xdef1.cc: original size 69, current size $shar_count"
fi
# ============= xdef2.cc ==============
if test -f 'xdef2.cc' && test X"$1" != X"-c"; then
echo 'x - skipping xdef2.cc (file already exists)'
else
echo 'x - extracting xdef2.cc (text)'
sed 's/^X//' << 'SHAR_EOF' > 'xdef2.cc' &&
#include "xdef.hh"
X
int const &
x2()
{
X Thingy q;
X return q.x();
}
SHAR_EOF
$shar_touch -am 0926232897 'xdef2.cc' &&
chmod 0644 'xdef2.cc' ||
echo 'restore of xdef2.cc failed'
shar_count="`wc -c < 'xdef2.cc'`"
test 69 -eq "$shar_count" ||
echo "xdef2.cc: original size 69, current size $shar_count"
fi
exit 0
More information about the Gcc-bugs
mailing list