This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Problems with -fno-implicit-templates
- To: egcs at cygnus dot com (egcs at cygnus dot com)
- Subject: Problems with -fno-implicit-templates
- From: Carlo Wood <carlo at runaway dot xs4all dot nl>
- Date: Wed, 5 Aug 1998 02:41:59 +0200 (CEST)
Problem 1 (or maybe correct according to the standard?)
=========
Consider the following small code snippet:
---------------foo.cc---------------------
class dstream { };
template <class TYPE>
dstream &operator<<(dstream &o, const TYPE &data) { return o; }
dstream& operator<<(dstream& o, const char *data) { return o; }
int main(void)
{
dstream d;
d << "a string constant";
}
------------------------------------------
This compiles fine with:
>g++ foo.cc
>nm -C a.out | grep operator
08048560 T operator<<(dstream &, char const *)
080485d0 W dstream & operator<<<char ()[17]>(dstream &, char ()[17] const &)
But it incorrectly(?) uses the template, and not the specialisation.
This becomes apparent with:
>g++ -fno-implicit-templates foo.cc
/tmp/cceZqrVa.o: In function `main':
/tmp/cceZqrVa.o(.text+0x24): undefined reference to `dstream & operator<<<char ()[17]>(dstream &, char ()[17] const &)'
collect2: ld returned 1 exit status
Note that adding a -W option (which should never change the code imho)
causes this to work:
>g++ -fno-implicit-templates -Wwrite-strings foo.cc
>nm -C a.out | grep operator
08048560 T operator<<(dstream &, char const *)
Apart from the fact that if we assume that WITHOUT -Wwrite-strings
we do not only not WARN when we write to a string, but we even make
it explicitly of type 'char [17]' (which is a bug I think; it should
still be 'const char [17]', even while it does not produce a warning/error
when converted to 'char *'), then shouldn't still the specialisation
be called - and not the template? I tried to understand the standard
at this point, but chapter 13 is way over my head :/
---
Problem 2 (not too urgent)
=========
Apart from this all, the reported type "char ()[17] const &" is not a
valid type: I can't use it as template instantiation if I want to:
template dstream & operator<<<char ()[17]>(dstream &, char ()[17] const &);
Then this results in an error:
traits.tig:3: `type name' declared as function returning an array
traits.tig:3: parse error before `const'
traits.tig:3: `operator <<(...)' must have an argument of class or enumerated type
traits.tig:3: `operator <<(...)' must take exactly two arguments
traits.tig:3: template-id `operator <<<int ()()>' for `operator <<(...)' does not match any template declaration
traits.tig:3: no matching template for `operator <<(...)' found
It seems impossible to instantiate this template manually (using
-fno-implicit-templates), while it DOES get instantiated automatically
as we saw above (without -fno-implicit-templates).
(In principle this makes -fno-implicit-templates unusable: It is possible
that a template instantiation is requested that can not be instantiated:
Output of nm -C foo.o:
U dstream & operator<<<char ()[17]>(dstream &, char ()[17] const &)
but no way to instantiate it).
---
Problem 3 (serious bug)
=========
Finally, I got a problem with -fno-implicit-templates in that it does
not generate virtual tables and type_info nodes and functions.
I use a work around for the operator<< problem, but still end up with the
following not instantiated templates: (without -fno-implicit-templates,
everything works fine).
g++ -ggdb -Wall -Woverloaded-virtual -Wpointer-arith -Winline -Werror -pipe -fno-implicit-templates -I../../include -I. -I- -c empty.cc
g++ empty.o -L/home/carlo/c++/libr/lib -lr -o empty
/home/carlo/c++/libr/lib/libr.so: undefined reference to `sock_dtct<no_input_ct, write_ostream_ct>::ios virtual table'
/home/carlo/c++/libr/lib/libr.so: undefined reference to `node_tct<sbll_node_ct, pe_fd_pair_dbct> virtual table'
/home/carlo/c++/libr/lib/libr.so: undefined reference to `dbbuf_fd_dtct<no_output_ct>::fd_dct virtual table'
/home/carlo/c++/libr/lib/libr.so: undefined reference to `node_tct<sbll_node_ct, expire_dct> type_info node'
/home/carlo/c++/libr/lib/libr.so: undefined reference to `file_dtct<write_ostream_ct>::ios virtual table'
/home/carlo/c++/libr/lib/libr.so: undefined reference to `iodbbuf_fd_dtct<debug_daemon_sock_input_ct, no_output_ct>::fd_dct virtual table'
/home/carlo/c++/libr/lib/libr.so: undefined reference to `node_tct<sbll_node_ct, pe_fd_pair_dbct> type_info function'
[..big snip..]
I believe this to be the same bug as I reported before, which was fixed by
Jason (thanks :), but not for -fno-implicit-templates apparently:
/usr/src/egcs/egcs-cvs/gcc/testsuite/g++.old-deja/g++.other>g++ virtual2.C
/usr/src/egcs/egcs-cvs/gcc/testsuite/g++.old-deja/g++.other>g++ -fno-implicit-templates virtual2.C
/tmp/ccZFQaD3.o: In function `B<A<C, D> >::B(void)':
/tmp/ccZFQaD3.o(.B<A<C, D> >::gnu.linkonce.t.(void)+0x8): undefined reference to `B<A<C, D> > virtual table'
collect2: ld returned 1 exit status
(I used my own test case, couldn't find back the g++.pt/virtual1.C
that you refer to in http://www.cygnus.com/ml/egcs/1998-Jul/0959.html
in the egcs-1.1 cvs version).
--
Carlo Wood <carlo@runaway.xs4all.nl>