[comp.lang.c++] strange binding of `*' in cfront 2.0, or is it?

peter@mit-amt.MEDIA.MIT.EDU (Peter Schroeder) (01/11/90)

class abstract{
private:
	static int i;
	static int *ptr2i;
	static int *ptr2j;
public:
	static int j;
};

// what is going on????
int abstract::*ptr2i = &abstract::i; // this bombs
int* abstract::ptr2i = &abstract::i; // this works

int abstract::*ptr2j = &abstract::j; // this works

// cfront 2.0 sez:
// "test.C", line 11: error:  ? cannot access abstract::i: private  member
//
// this is almost identical to the example given in the `Product Reference
// Manual', paragraph 9.4, page 60, where we have:
// 
//    process* process::run_chain = process::running;
//
//
// Somehow the placement of the `*' seems to be crucial here...
// 
// When I declare `int *i, j' the `*' binds to `i', not `int', since `j'
// ends up just an integer not pointer to integer. Hence I think
// writing `type class::*member' makes more sense then writing
// `type* class::member'. In any case the reported error is less then
// optimal especially since the syntax is acceptable in the `ptr2j' example.
//
//
// Enlightenment is appreciated!

// Peter
// peter@media-lab.media.mit.edu

pcg@rupert.cs.aber.ac.uk (Piercarlo Grandi) (01/15/90)

In article <1370@mit-amt.MEDIA.MIT.EDU>
peter@mit-amt.MEDIA.MIT.EDU (Peter Schroeder) writes:

   class abstract{
   private:
	   static int i;
	   static int *ptr2i;
	   static int *ptr2j;
   public:
	   static int j;
   };

   // what is going on????
   int abstract::*ptr2i = &abstract::i; // this bombs
   int* abstract::ptr2i = &abstract::i; // this works

   int abstract::*ptr2j = &abstract::j; // this works

This is almost all wrong. No suprise, because member pointers in
C++ are horridly botched.

    Ahhhhh. I am writing, and going to post, a fierce critique of two
    interrelated issue, member functions and pointers to members. In my
    opinion both are misdesigned. The former is a useless concept, and the
    latter has been got wrong as a consequence.

Your example fails because of the interplay between being a
static member naming and pointers to members, and plain typing
mistakes.

In C++ a pointer to a member means "pointer to a member of class
C with type T", and is declared with the syntax 'T C::* name'.
Also, in C++ static members with name N of class C are referred
to as 'C::N' from outside the class scope.

Your first problem is that in the class body you declared
'ptr2[ij]' to have type 'int *', not 'int abstract::*', to
follow your intention.

This notwithstanding, your second problem is that pointers to
static members are *not* member pointers (this is surely true for
static member functions, I dearly hope that for consistency --
hahahahah! -- it is true also for static member data).

Your second problem is that ptr2j and ptr2i are static members of
the same class, and thus their name outside the class is
"abstract::ptr2to[ij]', not 'ptr2to[ij]'.

Thus
	....	
	   static int i;
	   static int *ptr2i;
	....

   int abstract::*ptr2i = &abstract::i; // this bombs

exhibits *three* errors (at least).

Consider the following:

    struct s
    {
	int			i;
	static int		j;

	int			f();
	static int		g();

	static int		s::*ptoi;
	int			*ptoj;

	static int		(s::*ptof)();
	int			(*ptog)();

				s();
    } s1;

    static int	s::* s::ptoi	= &s1.i; // g++ 1.36.1 fails this; why?
    static int 	(s::* s::ptof)  = &s1.f;

    extern	s()
    :	ptoj(&s::j),
	ptog(&s::g)
    {}

This is diabolically subtle. Well, C++ is not for kids.

GNU C++ 1.36.1 will not accept the initialization of 's::ptoi',
claiming that the pointer types are incompatible. By now I am
quite confused myself, but I reckon it should be legal,
especially as the initialization of 's::ptof' is done without
complaint. GNU C++ 1.36.1 will put out funny complaints if the
above source is even slightly erroneously changed.

As to these:

   int* abstract::ptr2i = &abstract::i; // this works
   int abstract::*ptr2j = &abstract::j; // this works

Vagaries of the compiler... (actually a non function typed member
pointer can be safely converted to/from a non member pointer).

IMNHO opinion member pointers as they are now are a horrid kludge,
one of many caused by botching the definition of member functions.
Too bad that C++ 2.0 now is here to stay, Groucho would say.

	Just to make it clear: all this trouble happens because 'this'
	is an implicit parameter to a member function, and this	(pun
	intended!) has many unpleasant consequences.
--
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