Strange compiler warning

S

Sony Antony

I have the following simple program in Solaris Forte compiler 5.4
producing the warning. Though it produces the warning, it works fine
as expected.
This has been compiling fine without any warnings in the older 5.1
compiler. Since the latest compiler produces a warning, it makes me
suspecious about my own code. I still cannot find any problems with it
though.

It essentially produces a warning whenever a copy constructor of a
class with a pure virtual function invokes the pure virtual function
method on the instance that was passed to it.

Eg : -
class X {
public:
virtual void foo() = 0 ;
X (){}
X( X& x) { x.foo() ; }
}

Is this a compiler bug. Or am I wrong somewhere.
Thanks for the help
--sony



quark:/home/ffdfptz/t>CC -V
CC: Forte Developer 7 C++ 5.4 2002/03/09

quark:/home/ffdfptz/t>CC a.C
"a.C", line 13: Warning: Attempt to call a pure virtual function
XXX::foo() cons
t will always fail.
1 Warning(s) detected.


///////////////////////////////////Program

#include<iostream>
#include<string>

using namespace std ;

class XXX {
int i_ ;
virtual int foo() const = 0 ;
public:
XXX(){}
XXX( const XXX& x ) : i_( x.foo() ) {cout<<"hahha"<<i_<<endl ; }
};

class YY : public XXX {

int foo() const { return 13 ; }
public :
YY(){}
YY( const YY& y ) : XXX( y ) {}

};

int main( int argc, char* argv[] ){

YY y ;
YY x ( y ) ;
return 0 ;
}
 
V

Victor Bazarov

Sony Antony said:
I have the following simple program in Solaris Forte compiler 5.4
producing the warning. Though it produces the warning, it works fine
as expected.
This has been compiling fine without any warnings in the older 5.1
compiler. Since the latest compiler produces a warning, it makes me
suspecious about my own code. I still cannot find any problems with it
though.

It essentially produces a warning whenever a copy constructor of a
class with a pure virtual function invokes the pure virtual function
method on the instance that was passed to it.

Eg : -
class X {
public:
virtual void foo() = 0 ;
X (){}
X( X& x) { x.foo() ; }
}

Is this a compiler bug. Or am I wrong somewhere.

Virtual functions are resolved statically if called from constructors
or destructors. Calling a pure virtual function from a constructor or
a destructor causes undefined behaviour.

Victor
 
G

Gavin Deane

I have the following simple program in Solaris Forte compiler 5.4
producing the warning. Though it produces the warning, it works fine
as expected.
This has been compiling fine without any warnings in the older 5.1
compiler. Since the latest compiler produces a warning, it makes me
suspecious about my own code. I still cannot find any problems with it
though.

It essentially produces a warning whenever a copy constructor of a
class with a pure virtual function invokes the pure virtual function
method on the instance that was passed to it.

Eg : -
class X {
public:
virtual void foo() = 0 ;
X (){}
X( X& x) { x.foo() ; }
}

Is this a compiler bug. Or am I wrong somewhere.
Thanks for the help
--sony



quark:/home/ffdfptz/t>CC -V
CC: Forte Developer 7 C++ 5.4 2002/03/09

quark:/home/ffdfptz/t>CC a.C
"a.C", line 13: Warning: Attempt to call a pure virtual function
XXX::foo() cons
t will always fail.
1 Warning(s) detected.


///////////////////////////////////Program

#include<iostream>
#include<string>

using namespace std ;

class XXX {
int i_ ;
virtual int foo() const = 0 ;
public:
XXX(){}
XXX( const XXX& x ) : i_( x.foo() ) {cout<<"hahha"<<i_<<endl ; }
};

class YY : public XXX {

int foo() const { return 13 ; }
public :
YY(){}
YY( const YY& y ) : XXX( y ) {}

};

int main( int argc, char* argv[] ){

YY y ;
YY x ( y ) ;
return 0 ;
}

Comeau online compiles your code fine, with no warnings.
http://www.comeaucomputing.com/tryitout/

That's not an absolut guarantee of correctness, but there isn't much
it gets wrong. Bear in mind that the compiler is allowed to warn about
anything it likes. Perhaps they are tyring too hard to protect you.

GJD
 
T

Tom Groszko

Just guessing since I have never used that compiler.

When this constructor is running child classes have not yet been
constructed, so you should not call your childrens member functions, such
execution is I think undefined behaviour. Perhaps future versions of your
compiler may not allow this to happen. Which foo are you expecting to run
from here?

Tom
 
S

Sony Antony

"> > Is this a compiler bug. Or am I wrong somewhere.
Virtual functions are resolved statically if called from constructors
or destructors. Calling a pure virtual function from a constructor or
a destructor causes undefined behaviour.

But here the call was of a virtual function of *another* object that
has already been completely constructed elsewhere. ( IOW the virtual
function is not called on the object that is being constructed )
Are you saying that in general below code will fail to invoke foo()
polymorphically( undefined behavior ).

class X {
public:
X( some_type & y ) { y.foo() ; }
}

--sony
 
V

Victor Bazarov

Sony Antony said:
"> > Is this a compiler bug. Or am I wrong somewhere.

But here the call was of a virtual function of *another* object that
has already been completely constructed elsewhere. ( IOW the virtual
function is not called on the object that is being constructed )
Are you saying that in general below code will fail to invoke foo()
polymorphically( undefined behavior ).

No, in general it's impossible to tell. I can think of a couple
of ways to cause undefined behaviour with that.
class X {
public:
X( some_type & y ) { y.foo() ; }

What's 'some_type'?

Victor
 
D

David White

Sony Antony said:
I have the following simple program in Solaris Forte compiler 5.4
producing the warning. Though it produces the warning, it works fine
as expected.
This has been compiling fine without any warnings in the older 5.1
compiler. Since the latest compiler produces a warning, it makes me
suspecious about my own code. I still cannot find any problems with it
though.

It essentially produces a warning whenever a copy constructor of a
class with a pure virtual function invokes the pure virtual function
method on the instance that was passed to it.

Eg : -
class X {
public:
virtual void foo() = 0 ;
X (){}
X( X& x) { x.foo() ; }
}

Is this a compiler bug. Or am I wrong somewhere.
Thanks for the help

I think it's a compiler bug, caused by not distinguishing between the object
passed in and the object being constructed.

DW
 
S

Sony Antony

Victor Bazarov said:
No, in general it's impossible to tell. I can think of a couple
of ways to cause undefined behaviour with that.

I dont understand. I have a completely constructed object ( of
arbitrary type some_type below ). My understanding is that no matter
what once the object has been constructed completely, it should act
polymorphically. It should act
polymorphic even if the method is invoked within another object's
constructor.

Like the case below y is a completely constructed object. When I call
its foo(), where is the undefined behavior. The fact that I m calling
it inside X's constructor should not matter at all right.

Now in the original case both X and some_type happened to be of the
same type.

--sony
 
D

David White

Victor Bazarov said:
You are correct. However, the compiler does not know that when it
sees your constructor and a call to a function that it knows is pure
virtual. That's why it warns you.


That's why it's only a WARNING, not an error.

But it's an inappropriate and misleading warning isn't it? As the OP says,
there's no reason to believe that the object being copied is not a fully
constructed object. I suspect that if the code looked like this:

class X {
public:
virtual void foo() = 0 ;
X (){}
X( X& x) { foo() ; }
}

the compiler would also give a warning, not an error, even though it can
tell that this can't work. I think that's the warning it thinks it's giving
in the x.foo() case.
Exactly. If they are, what prevents you from writing

X x(x);

?

Can 'x' be in any state to be copied when it reaches the copy constructor?
This is where the warning ought to be :)

DW
 
V

Victor Bazarov

David White said:
But it's an inappropriate and misleading warning isn't it? As the OP says,
there's no reason to believe that the object being copied is not a fully
constructed object. I suspect that if the code looked like this:

class X {
public:
virtual void foo() = 0 ;
X (){}
X( X& x) { foo() ; }
} ;

the compiler would also give a warning, not an error, even though it can
tell that this can't work.

It CAN'T tell. That's the point. You are allowed to have a body
of 'virtual void foo() = 0' elsewhere. If such body is provided,
the call would be OK. Try it:

struct X {
virtual void foo() = 0;
X() { foo(); }
};

#include <iostream>
void X::foo() {
std::cout << "Gotcha!\n";
}

struct Y : X {
void foo() {}
};

int main() {
Y y;
return 0;
}
I think that's the warning it thinks it's giving
in the x.foo() case.


Can 'x' be in any state to be copied when it reaches the copy constructor?

Who said it was copying it? It's a parameterised constructor.
This is where the warning ought to be :)

Well, yes, here too. I actually think that the more warnings
the better.

Victor
 
D

David White

Victor Bazarov said:
It CAN'T tell. That's the point. You are allowed to have a body
of 'virtual void foo() = 0' elsewhere.

Oops. That's what I've telling other people recently. Okay, a warning is
appropriate in the above case, so forget that, but I still find it hard to
believe that the compiler warns in the x.foo() case because of the remote
possibility that x has not yet been constructed.

DW
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top