Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!samsung!zaphod.mps.ohio-state.edu!tut.cis.ohio-state.edu!arkesden.eng.sun.com!tiemann From: tiemann@arkesden.eng.sun.com (Michael Tiemann) Newsgroups: gnu.g++.bug Subject: Pointer to method bug on Sun4 Message-ID: <9002112007.AA26052@arkesden.sun.com> Date: 11 Feb 90 20:07:51 GMT References: <9002052129.AA27406@mondrian.ads.com> Sender: daemon@tut.cis.ohio-state.edu Reply-To: tiemann@sun.com Distribution: gnu Organization: GNUs Not Usenet Lines: 89 I have a code fragment which executes differently on a Sun 4 and a Sun 3. The Sun 3 version executes as intended; the Sun 4 version does not. The code has a method, make_child, which I invoke three different ways in this fragment. On a Sun 4, the third technique returns a different answer from the first two. On the Sun 3, all 3 techniques return the same value. The technique that fails is the case where the method is called via a pointer. When the technique fails, the returned value is the value of address of the object, i.e. "this" (although my code fragment doesn't print this to demonstrate it). What you have found is not a bug in GNU C++, but a bug in your program. Since I have seen others bitten before, I am posting it to the net. Had you run GNU C++ with -Wall or -Wreturn-type, the compiler would have found it for you. Also, to be honest, I'm not sure that the compilation of this code is really correct in either case; I appear unable to treat the ptr in the same manner as a function name as my copy of Lippmann indicates; i.e. in the code below you will find the line: (*m_c_ptr)(); My reading of Lippman indicates that I should be able to use: m_c_ptr(); I consider it bad practice to auto-dereference pointer-to-member functions. It is better that people see that they are really pointers. Otherwise, someone unfamiliar with the code could waste time looking for the definition of m_c_ptr as a function. but this results in compile time errors. I have also had troubles using the pointer from outside the class (i.e. I haven't been able to get anything like (parent->*m_child_ptr)() through the compiler) so I created the make_child2 method. I don't believe that this should be necessary. Probably another misunderstanding. If you want to use m_c_ptr in this way, you have to do this: (parent->*(parent->m_c_ptr))() You are not the first to run into this problem. Here is the source, as produced by the command "g++ -E" [edited by MDT]: extern "C" void printf (char *, ...); class childptr; typedef childptr* (childptr::*make_child_ptr)(); class childptr { public: childptr(); childptr* make_child(); childptr* make_child2(); make_child_ptr m_c_ptr; }; childptr* childptr::make_child() { childptr* newchild; newchild = new childptr; printf ("childptr::make_child returning %d\n", (int)newchild); return (newchild); } childptr* childptr::make_child2() { (*m_c_ptr)(); //^^^^^^^^^^^^^ bug: should be return (*m_c_ptr)(); } childptr::childptr() { m_c_ptr = make_child; } main() { childptr parent; childptr* parent2; childptr* child; child = parent.make_child(); printf ("parent.make_child yielded: %d\n\n", (int)child); parent2 = new childptr; child = parent2->make_child(); printf ("parent->make_child() yielded: %d\n\n", (int)child); child = parent2->make_child2(); printf ("parent->make_child2() yielded: %d\n\n", (int)child); }