This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

pointer to member/overload resolution confusion



The following program exposes a bug in

$ g++ -v
Reading specs from /usr/local/lib/gcc-lib/i586-pc-linux-gnulibc1/egcs-2.91.66/specs
gcc version egcs-2.91.66 19990314 (egcs-1.1.2 release)

The same bug shows up on solaris with egcs-1.1.2.

The bug was not present in 1.0.3.

The bug was originally found in code emitted by a commercial gui-builder.


------- t.C ------------------
void foo(void (*pf)())  ;

class A {
public:
    static void fnc() ;
    void fnc(void*) ;
    void goo() ;
} ;


void A::goo()
{
    foo(fnc) ;
}
------------------------------

$ g++ -S t.C
t.C: In method `void A::goo()':
t.C:14: warning: assuming & on `A::fnc(void *)'
t.C:14: warning: converting from `void (A::*)(void *)' to `void (*)()'

It's clear from the bogus warnings that the wrong fnc is being passed to
foo(), but just to be sure, here is the relevant portion of t.s

	    .file	"t.C"
	    .version	"01.01"
    gcc2_compiled.:
    .text
	    .align 4
    .globl goo__1A
	    .type	 goo__1A,@function
    goo__1A:
    .LFB1:
	    pushl %ebp
    .LCFI0:
	    movl %esp,%ebp
    .LCFI1:
	    pushl %ebx
    .LCFI2:
	    movl 8(%ebp),%ebx
	    pushl $fnc__1APv
    .LCFI3:
	    call foo__FPFv_v

$ c++filt fnc__1APv
A::fnc(void *)


There really is no overload resolution issue, because even in the scope
of A, fnc is _not_ a pointer to member.  See ISO/IEC 14882, section 5.3.1,

   "A pointer to member is only formed when an explicit & is used and its
   operand is a qualified-id not enclosed in parentheses. ...
   Nor is &unqualified-id a pointer to member, even within the scope
   of the unqualified=-id's class."


The following illegal program is accepted by g++:

--------------- t2.C ------------------------
class A ;
void foo(void (A::*pf)(void*))  ;

class A {
public:
    void fnc(void*) ;
    void goo() ;
} ;


void A::goo()
{
    foo(fnc) ;   // error fnc is not of type void (A::*)(void*)
                 // according to section 5.3.1 of standard.
}
---------------------------------------------

The following two legal modifications are accepted and g++ uses the correct
fnc which shows overload resolution is not the real problem with t1.C.

--------------------------- t3.C
void foo(void (*pf)())  ;

class A {
public:
    static void fnc() ;
    void fnc(void*) ;
    void goo() ;
} ;


void A::goo()
{
    foo(&A::fnc) ;   // fnc is void fnc(void)
}
---------------------------- t4.C

class A ;
void foo(void (A::*pf)(void*))  ;

class A {
public:
    static void fnc() ;
    void fnc(void*) ;
    void goo() ;
} ;


void A::goo()
{
    foo(&A::fnc) ; // fnc is void fnc(void*)
}
    
    
    
-- 
Mike Brennan
brennan@amc.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]