public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* pure virtual functions and name injection
@ 2006-03-06 21:02 Pierre Chatelier
  2006-03-06 21:11 ` John Love-Jensen
  0 siblings, 1 reply; 7+ messages in thread
From: Pierre Chatelier @ 2006-03-06 21:02 UTC (permalink / raw)
  To: gcc-help

Hello,

I have posted a message in the gcc mailing list, but it appears that  
what I thought that was a bug is in fact a misunderstanding of mine.
Here is the message:
http://gcc.gnu.org/ml/gcc/2006-03/msg00195.html

It can be summarized in "the following code does not compile"

//-------------------------------------
struct a
{
   virtual int foo() =0;
   virtual ~a(){}
};

struct b : public a
{
   virtual int foo(int a) =0;
   virtual ~b(){}
};

struct c : public b
{
int test()
{
return (foo() + // <--- the compiler claims here that it cannot find  
foo()
foo(2));
}
virtual ~c(){}
};

struct d : public c
{
   virtual int foo() {return 1;}
   virtual int foo(int a) {return a;}
   virtual ~d(){}
};

int main()
{
   d call;
   return call.test();
}
//-------------------------------------

The answer is  http://gcc.gnu.org/ml/gcc/2006-03/msg00196.html

> This is not a bug in gcc.  foo in b hides the one from a.
> You can "fix" the source by:
> struct b : public a
> {
>   virtual int foo(int a) =0;
>   using a::foo;
>   virtual ~b(){}
> };
>
> Which interjects foo from a into b's "namespace".

That's ok, but I do not understand what's going on. Why should I  
inject the "foo" name from a into b ? The two functions have  
different prototypes, I thought that the compiler was able to  
differentiate them.

Here is a follow-up to that problem:
if I *do not* use "using  a::foo;" but rather replaces
	return (foo() + foo(2));
by
	return (a::foo() + foo(2));
Then it compiles but there is a *link* error !
Can somebody explain me what happens ?

Thanks in advance,

Pierre Chatelier

^ permalink raw reply	[flat|nested] 7+ messages in thread
* Re: pure virtual functions and name injection
@ 2006-03-07  9:28 Jérôme Cornet
  2006-03-07 16:17 ` John Love-Jensen
  0 siblings, 1 reply; 7+ messages in thread
From: Jérôme Cornet @ 2006-03-07  9:28 UTC (permalink / raw)
  To: gcc-help

Hello,

i saw this message here on the mailing list archive:

http://gcc.gnu.org/ml/gcc-help/2006-03/msg00027.html

and followed the thread with great interest.

John Love-Jensen wrote:

> > The two functions have different prototypes, I thought that the  
> compiler was
> able to differentiate them.
>
> Different prototypes, but the same name.  The name is what is  
> causing the
> error, not the rest of the signature.

Ok, i guess this is because of the same name, but why is it ok with  
the C++ standard?

operator++(int) and operator++() do have the same name, but they are  
considered
as different by a c++ compiler...

> To avoid this kind of situation, I recommend using a different  
> method name
> for the method with the different signature.
>
> >Then it compiles but there is a *link* error !  Can somebody  
> explain me what
> happens ?
>
> You have not defined the a::foo function anywhere.  So there is a link
> error.

Technically, a::foo() is not "defined" anywhere (i understand what  
you mean),
but it does not need to, since it is a pure virtual functions.
But a::foo() is "implemented" in class "d" (return 1), so when  
calling a::foo() the
compiler should redirect the call to the implementation d::foo(), no?

jérôme cornet

^ permalink raw reply	[flat|nested] 7+ messages in thread
* Re: pure virtual functions and name injection
@ 2006-03-07 13:24 Pierre Chatelier
  0 siblings, 0 replies; 7+ messages in thread
From: Pierre Chatelier @ 2006-03-07 13:24 UTC (permalink / raw)
  To: gcc-help

>>  The two functions have different prototypes, I thought that the  
>> compiler was able to differentiate them.
>> Different prototypes, but the same name. The name is what is  
>> causing the error, not the rest of the signature.
>
> Ok, i guess this is because of the same name, but why is it ok with  
> the C++ standard?
> operator++(int) and operator++() do have the same name, but they  
> are considered as different by a c++ compiler...
Yes, but here it is a problem of visibility, not of resolving.

I think that the point is here :
>> It's a safety feature

> so when calling a::foo() the compiler should redirect the call to  
> the implementation d::foo(), no?
No, when you use the :: operator on a super-class, you explicitely  
ask not to use the "dynamic binding". Otherwise, it would be  
impossible to call the code of super-class
Take that simple example :

struct A
{
   virtual int f(void) {return 1;}
};

struct B : public A
{
   virtual int f(void) {return A::f();} //fortunately, it does not  
call B::f(), or it would be indefinitely recursive
};

Pierre Chatelier

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2006-03-07 16:17 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-03-06 21:02 pure virtual functions and name injection Pierre Chatelier
2006-03-06 21:11 ` John Love-Jensen
2006-03-06 21:28   ` Pierre Chatelier
2006-03-06 21:38     ` John Love-Jensen
2006-03-07  9:28 Jérôme Cornet
2006-03-07 16:17 ` John Love-Jensen
2006-03-07 13:24 Pierre Chatelier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).