Topic: HELP! C++-problem w/ templates


Author: jamshid@ses.com (Jamshid Afshar)
Date: Thu, 12 May 1994 01:38:42 GMT
Raw View
In article <CoxxGt.C8t@ucc.su.oz.au>,
John Max Skaller <maxtal@physics.su.OZ.AU> wrote:
>In article <Cou854.Gty@ses.com> jamshid@ses.com (Jamshid Afshar) writes:
>>[...recursive templates....]  Thank god ANSI/ISO C++ is clarifying
>>this issue and will require compilers to handle your code.
>
> _Has_ clarified it. Passed at San Diego. And thank
>John Spicer, not god :-)

Err, that's what I meant.  Surely no mere mortals could have produced
a C++ compiler as correct and robust as the one from Edison Design
Group [where John works].  I am continually amazed with their product
because every time I think I've whipped up some class or function
templates that will surely confuse it, EDG happily compiles it and
produces correct run-time results.  Those EDG guys must have
supernatural powers.  The only other possible explanation for the
quality is that they have continually sought out and tested their
compiler with C++ libraries like JCOOL and SPLASH instead of sitting
back until a high enough percentage of users complain about a
particular bug or until ANSI/ISO prints a golden copy of the C++
standard or until a competitor compiles code that they don't.  Nah, it
must be magic.

Jamshid Afshar
jamshid@ses.com




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Wed, 27 Apr 1994 23:05:16 GMT
Raw View
In article <Cou854.Gty@ses.com> jamshid@ses.com (Jamshid Afshar) writes:
>In article <1994Apr11.105436.29468@sat.mot.com>,
>Joseph Hall <hall_j@sat.mot.com> wrote:
>>Seems it was arminl@tschil.informatik.rwth-aachen.de (Armin Luetkenhaus) who said:
>>>I discovered a problem with forward-declared class templates
>>>resulting in a very strange behaviour of at least three C++-
>>>compilers. [...]
>>>--- snip ---
>>>template<class C> class A;
>>>template<class C> class B;
>>>template<class C> class A { B<C> *b; C c;};
>>>template<class C> class B { A<C> a;};
>>>int main() { B<CLASS1> b; A<CLASS2> a; return 0; }
>>>--- snap ---
>>
>>One would think that a compiler could figure out what the size of a member
>>of type (foo<bar> *) is without determing the layout of foo<bar>, but, alas,
>>g++ wasn't doing this last time I checked, and evidently neither are
>>the rest.
>>
>>Pretty annoying, isn't it?
>
>Extremely annoying!  I've been complaining to Borland for over two
>years about this problem.  It comes up often because template classes
>are often mutually dependent.  Thank god ANSI/ISO C++ is clarifying
>this issue and will require compilers to handle your code.

 _Has_ clarified it. Passed at San Diego. And thank
John Spicer, not god :-)

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: jamshid@ses.com (Jamshid Afshar)
Date: Sun, 1 May 1994 21:37:30 GMT
Raw View
In article <CovEwu.4vy@borland.com>,
Pete Becker <pete@genghis.interbase.borland.com> wrote:
>In article <Cou854.Gty@ses.com>, Jamshid Afshar <jamshid@ses.com> wrote:
>>>>template<class C> class A;
>>>>template<class C> class B;
>>>>template<class C> class A { B<C> *b; C c;};
>>>>template<class C> class B { A<C> a;};
>>>>int main() { B<CLASS1> b; A<CLASS2> a; return 0; }
>>>
>>>One would think that a compiler could figure out what the size of a member
>>>of type (foo<bar> *) is without determing the layout of foo<bar>, but,alas,
>>>g++ wasn't doing this last time I checked, and evidently neither are
>>>the rest.

Btw, the Edison Design Group's C++ front-end does handle recursive or
mutually dependent class template instantiation *very* well.  Watcom
C++ and BC++ 4.0 do better than Cfront or g++, but that's not saying
much.

>>>Pretty annoying, isn't it?
>>Extremely annoying!  I've been complaining to Borland for over two
>>years about this problem.
>
> I guess they must have been listening. It works fine in BC++ 4.0.

Sorry I didn't verify that the above exact code gives an error with
BC++ 4.0, but based on my description of the problem, swapping the
declarations of `b' and `a' should have been an obvious followup test.
If you swap those two variable definition BC++ 4.0 will give an error
(hence, extremely annoying).  As for whether Borland QA listens to me,
I have a directory full of old bug reports that prove otherwise.  One
of these bug reports is directly related to code like the above.  I
*first* reported it in August of 1992:

/* This has been sent to bugs@borland.com and TCPLUS-L.
Filenames: tmplinh.cpp
Compile: bcc -c tmplinh.cpp (BC++ 3.1)
Submitted by: Jamshid Afshar (jamshid@emx.utexas.edu) 512-471-1702
Problem:
   BC++ 3.1 doesn't allow a class template (Envelope<T>) which inherits
   from its parameter (Vector<T>) to be used in the class definition of
   the paramater.  I believe the following should compile without error,
   but I get an error when Envelope is defined.
Workaround:
   Wait for a much needed update of BC++.
*/

template<class Letter>
class Envelope;  // forward dec -- what you would do if non-template classes

template<class T>
class Vector {
public:
   void operator=(Envelope< Vector<T> >&);
};

template<class Letter>
class Envelope
   : public Letter {}; // BC++ ERROR: "Vector<int> must be previously defined"

typedef Vector<int> IntVector;








Author: pete@genghis.interbase.borland.com (Pete Becker)
Date: Mon, 2 May 1994 22:43:55 GMT
Raw View
In article <Cp582I.3GB@ses.com>, Jamshid Afshar <jamshid@ses.com> wrote:
>As for whether Borland QA listens to me,
>I have a directory full of old bug reports that prove otherwise.  One
>of these bug reports is directly related to code like the above.  I
>*first* reported it in August of 1992:

 Don't take it personally that your favorite bug hasn't been fixed yet.
The one that you mention turns out to be quite nasty to fix, and is being
worked on. Your name is well known around here: QA pays close attention.
 -- Pete




Author: jason@cygnus.com (Jason Merrill)
Date: Thu, 14 Apr 1994 08:46:41 GMT
Raw View
>>>>> Joseph Hall <hall_j@sat.mot.com> writes:

> One would think that a compiler could figure out what the size of a member
> of type (foo<bar> *) is without determing the layout of foo<bar>, but, alas,
> g++ wasn't doing this last time I checked, and evidently neither are
> the rest.

No, g++ still doesn't do that.  This is a known limitation, and I hope to
have it fixed for 2.6.0.  No promises, though...:)

> The ARM is mute on this topic, and I haven't seen anything relevant in
> Stroustrup's new book either.

The current working paper, however, is pretty clear on this point:

          template<class T> class Z {                                     ||
                  void f();                                               ||
                  void g();                                               ||
          };                                                              ||

          void h()                                                        ||
          {                                                               ||
                  Z<int> a;     // instantiation of class Z<int> required ||
                  Z<char>* p;   // instantiation of class Z<char> not required||
                  Z<double>* q; // instantiation of class Z<double> not required
||

                  a.f();  // instantiation of Z<int>::f() required        ||
                  p->g(); // instantiation of class Z<char> required, and ||
                          // instantiation of Z<char>::g() required       ||
          }                                                               ||

  Nothing in this example requires  class  Z<double>,  Z<int>::g(), or    |
  Z<char>::f()   to   be   instantiated.    An  implementation  may  not  |
  instantiate a function or a class that does not require instantiation.  |

Jason




Author: jamshid@ses.com (Jamshid Afshar)
Date: Mon, 25 Apr 1994 23:05:28 GMT
Raw View
In article <1994Apr11.105436.29468@sat.mot.com>,
Joseph Hall <hall_j@sat.mot.com> wrote:
>Seems it was arminl@tschil.informatik.rwth-aachen.de (Armin Luetkenhaus) who said:
>>I discovered a problem with forward-declared class templates
>>resulting in a very strange behaviour of at least three C++-
>>compilers. [...]
>>--- snip ---
>>template<class C> class A;
>>template<class C> class B;
>>template<class C> class A { B<C> *b; C c;};
>>template<class C> class B { A<C> a;};
>>int main() { B<CLASS1> b; A<CLASS2> a; return 0; }
>>--- snap ---
>
>One would think that a compiler could figure out what the size of a member
>of type (foo<bar> *) is without determing the layout of foo<bar>, but, alas,
>g++ wasn't doing this last time I checked, and evidently neither are
>the rest.
>
>Pretty annoying, isn't it?

Extremely annoying!  I've been complaining to Borland for over two
years about this problem.  It comes up often because template classes
are often mutually dependent.  Thank god ANSI/ISO C++ is clarifying
this issue and will require compilers to handle your code.  Basically,
class templates will be instantiated on a "need-to-know" basis (eg, if
you just declare a pointer to a template class, the compiler doesn't
need to instantiate ("expand") it).  This will force compiler writers
to fix their current compilers which do not allow the use of some
template classes even though non-template versions of the classes are
legal:

 class C {/*...*/};
 class B;
 class A { B* b; C c; };
 class B { A a; };
 int main() { B b; A a; return 0; }

See the comp.lang.c++ FAQ if you're interested in ordering the latest
ANSI/ISO Working Paper.

Jamshid Afshar
jamshid@ses.com




Author: pete@genghis.interbase.borland.com (Pete Becker)
Date: Tue, 26 Apr 1994 14:29:17 GMT
Raw View
In article <Cou854.Gty@ses.com>, Jamshid Afshar <jamshid@ses.com> wrote:
>>>template<class C> class A;
>>>template<class C> class B;
>>>template<class C> class A { B<C> *b; C c;};
>>>template<class C> class B { A<C> a;};
>>>int main() { B<CLASS1> b; A<CLASS2> a; return 0; }
>>
>>One would think that a compiler could figure out what the size of a member
>>of type (foo<bar> *) is without determing the layout of foo<bar>, but, alas,
>>g++ wasn't doing this last time I checked, and evidently neither are
>>the rest.
>>
>>Pretty annoying, isn't it?
>
>Extremely annoying!  I've been complaining to Borland for over two
>years about this problem.

 I guess they must have been listening. It works fine in BC++ 4.0.
 -- Pete




Author: arminl@tschil.informatik.rwth-aachen.de (Armin Luetkenhaus)
Date: 9 Apr 1994 14:40:31 GMT
Raw View
I discovered a problem with forward-declared class templates
resulting in a very strange behaviour of at least three C++-
compilers. These are the GNU gcc, version 2.5.7 for A/UX as well
as 2.5.8 for sparc, the SPARCompiler C++ 3.0, and Symantec's
C++ 6.0.1 for Macintosh.

Please note the following C++ code:

--- snip ---
template<class C> class A;
template<class C> class B;
template<class C> class A { B<C> *b; C c;};
template<class C> class B { A<C> a;};
int main() { B<CLASS1> b; A<CLASS2> a; return 0; }
--- snap ---

As long as TYPE1 and TYPE2 are identical, everything works
fine, but with a different TYPE1, all compilers give errors
like these (with TYPE1 set to "float" and TYPE2 set to "long"):

--- snip ---
nested.cc:4: field `a' has incomplete type
 (gcc)

File "nested.cc"; Line 4
Error:   size of A<long> is not known
 (SC++ for Mac)

"tst4.cc", line 4: error:  A undefined, size not known
"tst4.cc", line 4:       error detected during the instantiation of B <long >
 "tst4.cc", line 4:      the instantiation path was:
"tst4.cc", line 3:        template: B <long >
 "tst4.cc", line 5:       template: A <long >
 (SPARCompiler)
--- snap ---

WHAT IS THE PROBLEM? Any hints are welcome! Is it impossible to
define (specialize) a template class within another class template?


Thanx in advance
--- Armin ---

--
---
Armin Luetkenhaus, Am Friedrich 17, 52074 Aachen, Germany
EMail: arminl@pool.informatik.rwth-aachen.de





Author: hall_j@sat.mot.com (Joseph Hall)
Date: Mon, 11 Apr 1994 10:54:36 GMT
Raw View
Seems it was arminl@tschil.informatik.rwth-aachen.de (Armin Luetkenhaus) who said:
>I discovered a problem with forward-declared class templates
>resulting in a very strange behaviour of at least three C++-
>compilers. [...]
>
>--- snip ---
>template<class C> class A;
>template<class C> class B;
>template<class C> class A { B<C> *b; C c;};
>template<class C> class B { A<C> a;};
>int main() { B<CLASS1> b; A<CLASS2> a; return 0; }
>--- snap ---

One would think that a compiler could figure out what the size of a member
of type (foo<bar> *) is without determing the layout of foo<bar>, but, alas,
g++ wasn't doing this last time I checked, and evidently neither are
the rest.

Pretty annoying, isn't it?

The ARM is mute on this topic, and I haven't seen anything relevant in
Stroustrup's new book either.

--
Joseph Nathan Hall | Joseph's Law of Interface Design: Never give your users
Software Architect | a choice between the easy way and the right way.
Gorca Systems Inc. |                 joseph@joebloe.maple-shade.nj.us (home)
(on assignment)    | (602) 732-2549 (work)  Joseph_Hall-SC052C@email.mot.com