[gnu.g++.bug] possible bug in g++ 1.36.2

rfg@ICS.UCI.EDU (01/20/90)

// This may be a bug, then again, it may not be.

// It seems that both g++ and Cfront 2.0 effectively pre-scan
// each class declaration and process all data member declarations
// before then process any member function declarations.  This
// leads to the interesting error shown below.

// Note that Cfront 2.0 does not even allow the initializer for the static
// data member.

struct foo {

  void bar () {}

  static void (foo::*member_func) (void) = foo::bar;	/* ERROR */

};

// g++-01199001.bug.C:15: incomplete type `foo' does not have member `bar'

pcg@aber-cs.UUCP (Piercarlo Grandi) (01/23/90)

In article <9001190913.aa21588@ICS.UCI.EDU> rfg@ICS.UCI.EDU writes:
    // This may be a bug, then again, it may not be.
    
    // It seems that both g++ and Cfront 2.0 effectively pre-scan
    // each class declaration and process all data member declarations
    // before then process any member function declarations.

This is *required* by C++ 2.0; it is very regrettable, because
it is the *only* case in C or C++ where strict one pass
compilation is not possible, and has dire consequences for the
memory used by a compiler.

This rule is another nefarious consequence of the concept of
member functions (which could be abolished, with all its
attendant problems).

My advice, which is to *never* NEVER ****NEVER**** define a
memeber function in the class body, but to only declare it
there and define it after the class body, avoids many troubles,
and gives a break to the compiler.

    // This leads to the interesting error shown below.
    
    // Note that Cfront 2.0 does not even allow the initializer for the static
    // data member.

Hey! It should. I have this suspicion that your example is more
subtle than it looks at first sight.

    struct foo {
    
      void bar () {}
    
      static void (foo::*member_func) (void) = foo::bar;	/* ERROR */
    
    };
    
    // g++-01199001.bug.C:15: incomplete type `foo' does not have member `bar'

Notice also that the signature of 'bar' is 'bar()', while that
of '*member_func' is '(*member_func)(void)'. I don't know with
which options you compiled this...
-- 
Piercarlo "Peter" Grandi           | ARPA: pcg%cs.aber.ac.uk@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk