Boost logo

Boost :

From: Robert Ramey (ramey_at_[hidden])
Date: 2005-05-22 22:50:55


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
>> behavior.
>>
>> 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 14.7.1.7:
>>
>> "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;
}

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;
    ..
}

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.

Robert Ramey


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