Topic: template behaviour unspecified


Author: bparker@mailbox.uq.edu.au (Brian Parker)
Date: 1997/11/07
Raw View
The following issue was recently raised in comp.lang.c++.moderated-

The CD2, 14.7.1 [temp.inst]/7 specifies that it is undefined whether
virtual functions in a template class are implicitly instantiated, but
this means that if this virtual function uses the  template argument
in a manner not supported by the template argument, then the same code
will compile on some systems and not others.

e.g.
template<class T>
class C
{
public:
 virtual void f(T t ) { t.test();}
};

C<int> c; // fails on some implementations only

I think that the standard should specify the expected behaviour in
this case- the most flexible and consistent behaviour would be to not
instantiate unused virtual functions, but if that cannot be achieved
on all implementations then it should be specified that all virtual
functions MUST be instantiated. At least then one could be sure that
one's code is portable between implementations.

A similar case of undefined template behaviour is in 14.7.1/4

Any comments?
,Brian Parker.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Jean-Louis Leroy <jll@skynet.be>
Date: 1997/11/07
Raw View
> The following issue was recently raised in comp.lang.c++.moderated

Yep, by me. Thanks for reposting it here.

> I think that the standard should specify the expected behaviour in
> this case- the most flexible and consistent behaviour would be to not
> instantiate unused virtual functions, but if that cannot be achieved
> on all implementations then it should be specified that all virtual
> functions MUST be instantiated.

What about adding this rule: require that the virtual function table for a class
must be located in a file that contains the definition of a constructor for that
class. The rationale is that a ctor *statically* refers to the vtable. The
vtable, in turns, statically refers to the vfuncs.

We already have the rule that, inside a translation unit, a function template
should not be instantiated if it's not 'used'.

As I understand it, my example fails to compile because the vtable 'uses' the
templatized vfuncs.

The new rule would guarantee that a templatized vfunc would be instantiated in a
translation unit that contains the definition of a ctor for that class (or, to
be complete, a call to a vfunc on an object whose complete type is known). The
ctor, in turn, could only be instantiated in a module that uses it (this is
already the case). Thus program using templates, vfuncs and incomplete types
could then predict where it *must* make the full class definitions available.

The following would be required to compile, on all implementations (I've omitted
#include guards):

// Coll.hpp

template<class T>
struct Coll
   {
      Coll();
      virtual void prepare(T*);
   };

template<class T>
Coll<T>::Coll()
   {
   }

template<class T>
void Coll<T>::prepare(T* p)
   {
      p->save(); // line 11
   }

// a.hpp

struct A
    {
    void save();
    };

// b.hpp

#include "Coll.hpp"

struct A;

struct B
   {
   B();
   Coll<A> coll;
   // ...
   };

// b.cpp
#include "Coll.hpp"

B::B()
    {
    }

// Coll<A>::Coll() and  Coll<A>::save() may be instantiated here
// so we need the full class definition

// x.cpp
#include "b.hpp"

B b;

// function calls B::B(), which is located elsewhere
// no need to include "a.hpp" because module doesn't
// reference Coll<A>::Coll() nor Coll<A>::save()

If B has no explicit ctor, it is undefined whether the program should link. This
is because the compiler may generate a default ctor for B, e.g. if it has member
variables that have ctors.

While I think this would work, I agree it would do so in a less than obvious
manner. OTOH, this is a relatively minor addition to the standard. It doesn't
break any existing programs. Also, incomplete types are most useful in large
projects. Templates with vfuncs probably belong to libraries written by an
expert in Bottom C++. Any project using these constructs together should have
such an expert on board anyway...

Can members of the committee comment on this?

jl
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]