The included program does not appear to compile correctly under gcc 3.4.2. The following statement, which does not appear to work, begins on line 123 --
seq t /* sequence of size 1 */ ( seq /* sequence of size 2 */ ( seq /* sequence of size 2 */ ( a, b ), c ) ); where the struct seq has a number of constructors which are generated using function templates. The computer used for this test is an Intel 686 running Red Hat 7.3. This bug report is intended to be specifically for gcc-3.4.2. However, by way of information which may be of help or interest, I found that neither gcc-2.96 nor gcc-3.3 were able to compile the program at all. 1. Here is the compilation log for gcc-2.96 (installed by Red Hat) + g++ -v x1.cpp Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-110) /usr/lib/gcc-lib/i386-redhat-linux/2.96/cpp0 -lang-c++ -D__GNUG__=2 - D__EXCEPTIONS -v -D__GNUC__=2 -D__GNUC_MINOR__=96 -D__GNUC_PATCHLEVEL__=0 - D__ELF__ -Dunix -Dlinux -D__ELF__ -D__unix__ -D__linux__ -D__unix -D__linux - Asystem(posix) -D__NO_INLINE__ -Acpu(i386) -Amachine(i386) -Di386 -D__i386 - D__i386__ -D__tune_i386__ x1.cpp /tmp/ccWBU1FJ.ii GNU CPP version 2.96 20000731 (Red Hat Linux 7.3 2.96-110) (cpplib) (i386 Linux/ELF) ignoring nonexistent directory "/usr/i386-redhat-linux/include" #include "..." search starts here: #include <...> search starts here: /usr/include/g++-3 /usr/local/include /usr/lib/gcc-lib/i386-redhat-linux/2.96/include /usr/include End of search list. /usr/lib/gcc-lib/i386-redhat-linux/2.96/cc1plus /tmp/ccWBU1FJ.ii -quiet - dumpbase x1.cpp -version -o /tmp/ccmC63RA.s GNU C++ version 2.96 20000731 (Red Hat Linux 7.3 2.96-110) (i386-redhat-linux) compiled by GNU C version 2.96 20000731 (Red Hat Linux 7.3 2.96-110). x1.cpp: In function `int main ()': x1.cpp:131: parse error before `,' x1.cpp:146: request for member `u' in `t', which is of non-aggregate type `seq () (...)' A similar result was obtained using gcc-3.3. 2. Here is the compilation log for gcc-3.4.2 -- + g++ -v x1.cpp Reading specs from /usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2/specs Configured with: ../gcc-3.4.2/configure --enable-__cxa_atexit Thread model: posix gcc version 3.4.2 /usr/local/libexec/gcc/i686-pc-linux-gnu/3.4.2/cc1plus -quiet -v -D_GNU_SOURCE x1.cpp -quiet -dumpbase x1.cpp -mtune=pentiumpro -auxbase x1 -version - o /tmp/ccM4JlhE.s ignoring nonexistent directory "NONE/include" ignoring nonexistent directory "/usr/local/lib/gcc/i686-pc-linux- gnu/3.4.2/../../../../i686-pc-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2 /usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../include/c++/3.4.2/i686- pc-linux-gnu /usr/local/lib/gcc/i686-pc-linux- gnu/3.4.2/../../../../include/c++/3.4.2/backward /usr/local/include /usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2/include /usr/include End of search list. GNU C++ version 3.4.2 (i686-pc-linux-gnu) compiled by GNU C version 3.4.2. GGC heuristics: --param ggc-min-expand=47 --param ggc-min-heapsize=31978 /usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../i686-pc-linux- gnu/bin/as -V -Qy -o /tmp/ccvsdtHy.o /tmp/ccM4JlhE.s GNU assembler version 2.13.2.1 (i686-pc-linux-gnu) using BFD version 2.13.2.1 /usr/local/libexec/gcc/i686-pc-linux-gnu/3.4.2/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld- linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o /usr/local/lib/gcc/i686-pc-linux- gnu/3.4.2/crtbegin.o -L/usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2 - L/usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2/../../../../i686-pc-linux-gnu/lib - L/usr/local/lib/gcc/i686-pc-linux-gnu/3.4.2/../../.. /tmp/ccvsdtHy.o -lstdc++ - lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/local/lib/gcc/i686-pc-linux- gnu/3.4.2/crtend.o /usr/lib/crtn.o This compile was apparently successful. But the program did not function as expected. 3. Here is the program x1.cpp which includes further discussion of its purpose and the problem encountered in its comments -- #include <iostream> #include <vector> using namespace std; /* This program implements a small variable length (up to 3 elements) */ /* polymorphic sequence called seq. */ /* The idea is that */ /* seq x(1); /* causes x to contain the int 1 */ /* seq y(1, 2.6); /* causes y to contain the int and double */ /* seq z(1, 2.3, "hi"); /* causes z to contain the int, double */ /* /* and const char * */ /* The program is based on the usual approach of using a container */ /* (std::vector) to hold pointers to a common base class, here U. */ struct U {virtual ~U() {}}; /* What the common base class is the base of is the following template */ /* class, V, which is a shallow wrapper for the various values in the */ /* sequence. */ /* Note that this implementation is quite rudimentary and direct. */ /* All needed values are simply copied. There is no attempt at */ /* data sharing or memory management. */ template <class T> struct V : U { T v; /* contained value */ V(T v) : v(v) {} /* copy construcor */ }; /* The polymorphic container is not itself a template but it does */ /* have three template constructors: one for a single argument, one */ /* for two arguments, and one for three arguments. The idea is */ /* that these arguments can be objects of any type. */ /* Each constructor makes an instance of the wrapper V of the */ /* approriate type in dynamic memory for each of its arguments, */ /* This instance is initialized using the value of the corresponding */ /* argument. The location of each V is upcast to a U *, */ /* pointer to the base class of V, and pushed into the vector u */ /* which defines the sequence. */ /* Note that because these constructors are function templates the */ /* types of the various aruments are being deduced from the call. */ struct seq { vector<U *> u; /* elements */ seq () { cout << "0 arg default constructor called" << endl; } template <class A> seq(A a) { cout << "1 arg template constructor called" << endl; u.push_back(dynamic_cast<U *>(new V<A>(a))); } template <class A, class B> seq(A a, B b) { cout << "2 arg template constructor called" << endl; u.push_back(dynamic_cast<U *>(new V<A>(a))); u.push_back(dynamic_cast<U *>(new V<B>(b))); } template <class A, class B, class C> seq(A a, B b, C c) { cout << "3 arg template constructor called" << endl; u.push_back(dynamic_cast<U *>(new V<A>(a))); u.push_back(dynamic_cast<U *>(new V<B>(b))); u.push_back(dynamic_cast<U *>(new V<C>(c))); } }; /* Scratch types for testing seq */ struct A {}; struct B {}; struct C {}; /* It is hard to imagine a simpler polymorphic container. Here is */ /* the test. */ main() { /* First, a test of scalars */ seq z(1, 2.3, "hi"); /* This works perfectly. The following output statements print */ /* the correct values: */ /* 1 */ /* 2.3 */ /* hi */ cout << dynamic_cast<V<int> *>(z.u[0])->v << endl; cout << dynamic_cast<V<double> *>(z.u[1])->v << endl; cout << dynamic_cast<V<const char *> *>(z.u[2])->v << endl; /* Test of recursive structure */ A a; B b; C c; /* The following statement will not compile using either gcc 2.96 or */ /* 3.3. It does compile using gcc 3.4.2. */ seq t /* sequence of size 1 */ ( seq /* sequence of size 2 */ ( seq /* sequence of size 2 */ ( a, b ), c ) ); /* However, the resulting code does not appear to be correct since, */ /* as a result of executing this statement, which calls three seq */ /* constructors, the program prints only the following two lines -- */ /* 2 arg template constructor called */ /* 2 arg template constructor called */ /* indicating that, somehow, the outtermost constructor, the one */ /* with only one argument, is not being called. Then, executing */ cout << "t.u.size() = " << t.u.size() << endl; /* prints */ /* t.u.size() = 2 */ /* but the size of t.u should be 1. */ } -- Summary: nested calls to template constructors generate incorrect result Product: gcc Version: 3.4.2 Status: UNCONFIRMED Severity: normal Priority: P2 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: bill at graysoft dot com CC: gcc-bugs at gcc dot gnu dot org GCC host triplet: i686-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=18028