This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: glossary for egcs - request for contributions
- To: espie at quatramaran dot ens dot fr (Marc Espie)
- Subject: Re: glossary for egcs - request for contributions
- From: Joe Buck <jbuck at Synopsys dot COM>
- Date: Wed, 28 Apr 99 23:48:02 PDT
- Cc: jbuck at Synopsys dot COM, egcs at egcs dot cygnus dot com
> >> For C++, 'covariant return types', and 'contravariance violation' are
> >> probably most frequently confusing.
>
> >I can't think of any explanation for these errors that doesn't require at
> >least a paragraph. Maybe we should add a URL or reference to a node in
> >gcc.info, or both, to the error message, since it seems that when people
> >encounter them they immediately post to gnu.g++.help or egcs.
>
> Is there any online paper that clearly explains, in understandable words,
> what covariant/contravariant means in an object type theory ?
No, we'd have to write a note. Let me know if you think the following is
intuitive. I'm just dashing it off so there may be syntax errors. Note
that I'm using the C++ terms (base class, derived class) not the typical
terms from type theory (subclass/superclass).
covariant: varying in the same way as. If a language feature is covariant
one may replace a class by a derived class. e.g. I can overload a virtual
function
Base* Base::clone() const { return new Base(*this);}
with
Derived* Derived::clone() const { return new Derived(*this);}
return types are covariant: when the class changes from Base to Derived,
the return type changes in the same way.
contravariant: varying in the opposite way as. If a language feature is
contravariant, one may replace a class by a class that it is derived
from.
Function arguments, for pointers to functions, are contravariant.
If I have
typedef int (*PFBase)(Base&);
naive users think that
int dfunc(Derived&);
PFBase p = &dfunc;
should be legal, since they are used to convariance. But this is broken,
since if it were legal I could pass a Base object to dfunc. Instead,
if I have
typedef int (*PFDerived)(Derived&);
int bfunc(Base&);
PFDerived p = &bfunc;
this is legal: I replaced a more derived by a less derived class.