🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

2 total messages Started by Seth C. Goldstein Mon, 23 Nov 1992 11:32
what is a "contravarience violation for method types"
#603
Author: Seth C. Goldstein
Date: Mon, 23 Nov 1992 11:32
35 lines
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"
#604
Author: Joe Buck
Date: Mon, 23 Nov 1992 20:06
110 lines
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