19980824 bugs in initializing static const members

Reid M. Pinchback reidmp@MIT.EDU
Wed Aug 26 13:15:00 GMT 1998


I'm using 19980824 on a alpha-dec-osf4.0d, ran into what appears
to be some bugs related to the handling of initialization in
static const data members.  Experts on the standard may determine
some of this to be ok behaviour, even if it evidences itself
in egcs in less-than-verbose ways.

Code follows.

========================== 8< cut here 8< ==========================

/*
** to compile:
**    g++ -c bug.c -o bug
**
** with exactly one of the following defines:
** A. USE_IS       (assign variable using a static data member 'is')
** B. USE_HAS      (assign variable using static method, still compile 'is')
** C. ONLY_USE_HAS (assign variable using static method, don't compile 'is')
**
** and any combination (including none) of the following defines:
** X. USE_METHOD   (use the static method 'f' in 'has' and to initialize 'is';
**                  if undefined use the global function 'f1' instead)
** Y. USE_TMPL     (use the templated form of the class; the actual
**                  template parameter won't be used for anything)
**
** to get the results:
** A.      bug.cpp:45: field initializer is not constant
** 
** A+X.    bug.cpp:45: warning: implicit declaration of function `int f(...)'
**         bug.cpp:45: field initializer is not constant
**
** A+Y.    /usr/bin/ld:
**         Unresolved:
**         foo<int>::is
**         collect2: ld returned 1 exit status
**
** A+X+Y.  /usr/bin/ld:
**         Unresolved:
**         foo<int>::is
**         collect2: ld returned 1 exit status
**
** B.      bug.cpp:45: field initializer is not constant
**
** B+X.    bug.cpp:45: warning: implicit declaration of function `int f(...)'
**         bug.cpp:45: field initializer is not constant
**
** B+Y.    (no compiler or linker error)
**
** B+X+Y.  (no compiler or linker error)
**
** C.      (no compiler or linker error)
**
** C+X.    (no compiler or linker error)
**
** C+Y.    (no compiler or linker error)
**
** C+X+Y.  (no compiler or linker error)
**
** conclusions:
**   I was surprised that A and B don't compile, but this might be
**   behaviour the standard requires in spite of the inlining?
**
**   I believe that the A+Y, A+X+Y results are wrong (there should
**   be no need to link anything)
**
**   The warnings in A+X and B+X sound like a parsing buglet to me
**   (the method f() is in scope and it has bool, not int, as a return type)
**
**   I find it odd that the B and B+Y tests gave different results,
**   ditto for B+X versus B+X+Y; if B and B+X aren't legal C++ then
**   wouldn't instantiating the template in B+Y and B+X+Y result in
**   a comparable complaint for the static data member?  I know
**   methods are only instantiated if used; maybe the same applies
**   to data members of template classes
**
**   C, C+X, C+Y, C+X+Y all work as I believe they should
*/

bool f1() { return true; }

#if defined(USE_METHOD)
#define F f
#else
#define F f1
#endif

#if defined(USE_TMPL)
template <class A>
#endif
struct foo {
  inline static bool f() { return true; }
#if !defined(ONLY_USE_HAS)
  static const bool is=F();
#endif
  inline static bool has() { return F(); }
};

struct bar {
#if defined(USE_TMPL)
  typedef foo<int> type;
#else
  typedef foo type;
#endif
#if defined(USE_IS)
  static void g() { bool b=type::is; }
#elif defined(USE_HAS) || defined(ONLY_USE_HAS)
  static void g() { bool b=type::has(); }
#else
  #error "Must #define one of USE_IS, USE_HAS, ONLY_USE_HAS"
#endif
};
 
 
main(int argc, char * argv[]) {
  bar::g();
}

========================== 8< cut here 8< ==========================
 
 
====================================================
= Reid M. Pinchback                                =
= I/T Delivery, MIT                                =
=                                                  =
= Email:   reidmp@mit.edu                          =
= URL:     http://web.mit.edu/reidmp/www/home.html =
====================================================




More information about the Gcc-bugs mailing list