Boost logo

Boost :

From: Rene Rivera (grafik.list_at_[hidden])
Date: 2005-05-22 23:50:19

Robert Ramey wrote:
> David Abrahams wrote:
>>Rene Rivera <grafik.list_at_[hidden]> writes:
>>>Many of the problems that CodeWarrior, and True64, have with the
>>>serialization library stem from the behavior of CW to not call
>>>constructors for static data members in one particular class in the
>>>library. I've come to think that this is standard conforming
>>>The serialization library relies on a static member of a template
>>>class being constructed at global initialization time to figure out
>>>what all
>>>the serialized classes are. The problem is that the template class is
>>>being instantiated implicitly. Which for most compilers also
>>>instantiates any static members of that template class. It's my
>>>understanding that this violates
>>>"The implicit instantiation of a class template does not cause any
>>>static data members of that class to be implicitly instantiated."
>>>Question I have.. Is my understanding correct? Or is this a bug in
>>>CW part?
>>Your understanding is certainly correct. It's standard practice in
>>traits templates, for example, to do something like:
>>template <class T>
>>struct is_whatever
>> static T& x;
>> template <class U>
>> char test(U&);
>> template <class U>
>> char (& test( whatever<U>& ) )[2];
>> enum { value = sizeof(test(x)) == 2 };
>>Nobody ever even writes an initializer for x.
> This is different than our case. we have:
> template<class T>
> struct A {
> static T t;
> ...
> };
> template<class T>
> T A<T>::t
> and somewhere in the program we do
> void f(){
> T & t = A<T>::t;
> }

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;

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 refers to. --
Well at least not clear to me :-) But does say this... which
possibly supports what says. "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."

> 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. The only circumstance it generates the init
function is one explicitly defines the member:

struct B;
template A<B>::t;

> Now Rene has looked into this and raises the possibility that CW is correct
> in its behavior - and all the other compilers are wrong. Rene's quote from
> the standard would suggest to me that A<T>::t should never even be
> instantiated. If that's the case why is A<T>::t even being allocated?
> This is quite murky to me.

Somewhat murky for me also. I think this not an area of compilers that
gets exercised this way.

-- Grafik - Don't Assume Anything
-- Redshift Software, Inc. -
-- rrivera/ - grafik/
-- 102708583/icq - grafikrobot/aim - Grafik/

Boost list run by bdawes at, gregod at, cpdaniel at, john at