Thread View: gnu.g++.help
2 messages
2 total messages
Started by Seth C. Goldstein
Mon, 23 Nov 1992 11:32
what is a "contravarience violation for method types"
Author: Seth C. Goldstein
Date: Mon, 23 Nov 1992 11:32
Date: Mon, 23 Nov 1992 11:32
35 lines
1103 bytes
1103 bytes
When compiling the following with g++-2.3.1 I get warnings of the form:
quad.C: In method `Toplevel::Toplevel ()':
quad.C:27: warning: contravariance violation for method types ignored
What does it mean?
example:
////////////////////////////////////////////////////////////////////////
class Frame;
typedef void (Frame::*Codeblock)(void);
class Frame
{
protected:
int counter;
public:
inline Frame(Codeblock function);
};
class Toplevel : Frame
{
int i;
public:
Toplevel(void);
void runtop(void);
};
Toplevel::Toplevel(void) : Frame(&(Toplevel::runtop)) // line 27
{
}
-seth
Re: what is a "contravarience violation for method types"
Author: Joe Buck
Date: Mon, 23 Nov 1992 20:06
Date: Mon, 23 Nov 1992 20:06
110 lines
3633 bytes
3633 bytes
In article <SETHG.92Nov23113233@roar.CS.Berkeley.EDU> sethg@roar.CS.Berkeley.EDU (Seth C. Goldstein) writes:
>When compiling the following with g++-2.3.1 I get warnings of the form:
>
>quad.C: In method `Toplevel::Toplevel ()':
>quad.C:27: warning: contravariance violation for method types ignored
>
>What does it mean?
>
>example:
>////////////////////////////////////////////////////////////////////////
>class Frame;
>typedef void (Frame::*Codeblock)(void);
>
>class Frame
>{
>protected:
> int counter;
>
>public:
> inline Frame(Codeblock function);
>};
>
>class Toplevel : Frame
>{
> int i;
>public:
> Toplevel(void);
> void runtop(void);
>};
>
>Toplevel::Toplevel(void) : Frame(&(Toplevel::runtop)) // line 27
>{
>
>}
This is a horribly phrased error message, but I don't know of a short
way to describe the problem. You are using a pointer to a Toplevel
member function where a pointer to a Frame function is desired. This
is a no-no. Here's why: assume the code were written this way:
typedef void (Frame::*Codeblock)(void);
class Frame {
Codeblock funcP;
public:
Frame(Codeblock function);
void doItTo(Frame&);
};
class Toplevel : Frame
{
int i;
public:
Toplevel(void);
void runtop(void);
};
Toplevel::Toplevel(void) : Frame(&(Toplevel::runtop)) {}
void Toplevel::runTop() { i = 1;}
// Now here's where the problem comes from:
void Frame::doItTo(Frame& arg) {
arg.funcP();
}
Note that arg can be any Frame object, not necessarily a TopLevel.
Now consider the following code:
TopLevel foo;
Frame bar;
foo.doItTo(bar);
We will now attempt to set bar's "i" member to 1 -- but bar has no
i member because it is not a TopLevel. Result: a crash, or who knows
what.
Pointers to member functions "inherit backwards", hence the word
"contravariant" among the compiler folks. Given
class Base...
class Derived: public Base...
typedef void (Base::*VoidBaseFuncP)(void);
typedef void (Derived::*VoidDerivedFuncP)(void);
then it is legal to assign a VoidBaseFuncP to a VoidDerivedFuncP without
a cast, but not vice versa. This is exactly the reverse of the behavior
for pointers to objects, where it is legal to assign a Derived* pointer
to a Base* pointer without a cast, but not vice versa.
Now in your case, you may be able to assure that the TopLevel function
will never be called on a non-TopLevel object through the pointer (perhaps
because functions like doItTo are not present and the function is only
applied to the object itself). In that case, use a cast to make the
warning disappear, but remember that casts tell the compiler "Don't bother
me, I know what I am doing", so make sure you are!
I would ask the g++ maintainers to consider rephrasing the error message
to something like
warning: unsafe to assign pointer to member of derived class (class YYY)
to pointer to member of base (class XXX)
though I am not sure that this phrasing covers all the situations in which
the present message can be issued.
--
Joe Buck jbuck@ohm.berkeley.edu
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads