This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Problems with -fno-implicit-templates


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>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]