Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!mcsun!ukc!dcl-cs!aber-cs!rupert!pcg From: pcg@rupert.cs.aber.ac.uk (Piercarlo Grandi) Newsgroups: comp.lang.c++ Subject: Re: strange binding of `*' in cfront 2.0, or is it? Summary: member pointers are a horrid botch Message-ID: Date: 15 Jan 90 14:42:58 GMT References: <1370@mit-amt.MEDIA.MIT.EDU> Sender: pcg@aber-cs.UUCP Organization: Coleg Prifysgol Cymru Lines: 114 In-reply-to: peter@mit-amt.MEDIA.MIT.EDU's message of 10 Jan 90 22:20:29 GMT 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