This is the mail archive of the libstdc++@sourceware.cygnus.com mailing list for the libstdc++ project. See the libstdc++ home page for more information.


[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index] [Subject Index] [Author Index] [Thread Index]

Static data members in template declarations




Some existing code uses constructs like this:

  template <class T> 
  struct S { 
    enum E { a };
    static T t[a];
  };

  template <class T>
  T S<T>::t[S<T>::a];

(Notably, stl_alloc.h in the SGI STL distribution.)

This code is, IMO, only questionably legal, and with my last checkin EGCS
no longer accepts it, complaining that the two array declarations do
not have the same type.

The issue is whether the `a' in the first declaration is the same as
the `S<T>::a' in the second declaration.  Since the first `a' is not
type-dependent EGCS resolves it to be the enumeration constant.
However, in the array definition `S<T>::a' is type-dependent, and is
not resolved.  This causes the code that compares the array bounds to
see if the redeclaration is legal to complain.

The way to write the definition correctly is:

  template <class T>
  T S<T>::t[a];

which does work with the current EGCS.  I've checked in the appended
patch to EGCS's STL to make exactly this change.

I'm interested in other people's opinions of my interpretation of the
standard here.  Obviously, in some cases, like this one, some amount
of cleverness in the compiler could make the case above "work".  In
particular, the name-lookup routines could handle `S<T>::a' specially,
noticing that `S<T>' is the same as the class in whose scope the
definition is occurring. 

-- 
Mark Mitchell 			mark@markmitchell.com
Mark Mitchell Consulting	http://www.markmitchell.com

1998-11-01  Mark Mitchell  <mark@markmitchell.com>

	* stl_alloc.h (default_alloc_template::_S_free_list): Don't
	qualify _NFREELISTS.

Index: stl_alloc.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/libstdc++/stl/stl_alloc.h,v
retrieving revision 1.4
diff -c -p -r1.4 stl_alloc.h
*** stl_alloc.h	1998/09/02 17:24:43	1.4
--- stl_alloc.h	1998/11/02 00:44:19
*************** size_t __default_alloc_template<__thread
*** 679,689 ****
  template <bool __threads, int __inst>
  __default_alloc_template<__threads, __inst>::_Obj* __VOLATILE
  __default_alloc_template<__threads, __inst> ::_S_free_list[
- # ifdef __SUNPRO_CC
      _NFREELISTS
- # else
-     __default_alloc_template<__threads, __inst>::_NFREELISTS
- # endif
  ] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
  // The 16 zeros are necessary to make version 4.1 of the SunPro
  // compiler happy.  Otherwise it appears to allocate too little
--- 679,685 ----