Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2005-05-23 07:38:33


Rene Rivera <grafik.list_at_[hidden]> writes:

> To correct that a bit.. In the code in question we actually do the
> equivalent of:
>
> template <typename T>
> void f() {
> void * t = &A<T>::t;
> }

That clearly requires A<T>::t to exist, and thus causes its
instantiation:

  14.7.1 Implicit instantiation [temp.inst]

  1 Unless a class template specialization has been explicitly
  instantiated (14.7.2) or explicitly specialized (14.7.3), the class
  template specialization is implicitly instantiated when the
  specialization is referenced in a context that requires a
  completely-defined object type or when the completeness of the class
  type affects the semantics of the program. The implicit
  instantiation of a class template specialization causes the implicit
  instantiation of the declarations, but not of the definitions or
  default arguments, of the class member functions, member classes,
  static data members and member templates; and it causes the implicit
  instantiation of the definitions of member anonymous unions. Unless
  a member of a class template or a member template has been
  explicitly instantiated or explicitly specialized, the
  specialization of the member is implicitly instantiated when the
  specialization is referenced in a context that requires the member
  definition to exist; in particular, the initialization (and any
  associated side-effects) of a static data member does not occur
  unless the static data member is itself used in a way that requires
  the definition of the static data member to exist.

Note in particular that last sentence.
>
> Hence the implicit aspect of the instantiation. Which I think CW decides
> is not sufficient for the semantic requirement that the other rules in
> 14.7.1 refer to. But it's not clear how the other rules of 14.7.1 should
> apply for the implicit instantiation case that 14.7.1.7 refers
> to. --

I think you mean 14.7.1¶7 or 14.7.1/7 if you prefer.

> Well at least not clear to me :-) But 14.7.1.1 does say this... which
> possibly supports what 14.7.1.7 says.
>
> 14.7.1.1: "The implicit instantiation of a class template specialization
> causes the implicit instantiation of the declarations, _but not of the
> definitions_ or default arguments, of the class member functions, member
> classes, _static data members_ and member templates; and it causes the
> implicit instantiation of the definitions of member anonymous unions."

But you missed the most important part of that paragraph ;-)

>> We expect A<T>::t to be instanticiated and the program to link and run as
>> expected. In fact on most compilers it does this. This group includes
>> those known to be the most conforming ones including the latest GCC, VC and
>> Comeau compilers.
>> With CW, it seems that A<T> t is allocated but the constructor for t
>> isn't
>> being called - at least at pre-compile time. It might be being called on
>> first usage as it would be in the following case.
>> void f() {
>> static T t;
>> ..
>> }
>
> It's not getting called, no matter what. Or more precisely CW is not
> adding the constructor+instance to the global initialization function
> list that CW generates.

I think it's a bug and should be reported to MW, but that said, check
out boost/python/detail/force_instantiate.hpp, which I use for this
exact purpose.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk