Topic: Legality of & operator on a reference to an incomplete class
Author: jbuck@forney.berkeley.edu (Joe Buck)
Date: 21 Apr 1992 01:04:53 GMT Raw View
Consider the following code:
class Foo;
void bar(Foo*);
void bletch(Foo& arg) {
bar(&arg);
}
What's going on is this: the complete definition of class Foo is not
known. We have a function that takes a pointer to Foo and a function
that takes a reference to Foo. The question is this: is this code legal?
It is accepted by cfront 2.1 and g++ 1.40.3. It is rejected by g++ 2.0
and later, on purpose.
The rationale for the restriction (pardon me, Mike Tiemann or Mike Stump,
if I misquote either of you) is this: class Foo might want to overload the &
operator. Thus this use of the & operator (using its builtin meaning)
must be rejected. Hence the g++ error message
"cannot lookup method in incomplete type"
which confused me a good deal since I didn't think I was invoking a method.
My feeling is that when incomplete class definitions are operated on,
the "standard thing" should happen where "standard thing" means something.
One precedent for this is in pointers to incomplete class objects: the
compiler happily accepts
class B;
class D;
void func() {
B* foo;
D* bar;
bar = (D*)foo;
}
even when B and D are incomplete classes, and even though if a multiple
inheritance relation between them exists, the compiler would need to
generate different code.
I'm willing to accept either answer to this question, but I prefer to
do as much as possible with incomplete class definitions; the possibility
of a rare operation, like defining operator&, shouldn't force the
inclusion of class definitions that are otherwise unnecessary; compilation
in large projects takes long enough already.
I don't think that the ARM really addresses this question rigorously.
Mike and Mike have quoted me sections that suggest an answer, but they
seem ambiguous to me. Example:
"According to ARM into Chapter 5, it states, ``This section defines the
operators when applied to type for which they have not been
overloaded. ... We repeat: the rules in this chapter do not cover
expressions involving overloaded operators or user-defined conversion
operations.''"
So? The compiler has not seen an overloaded operator or user-defined
conversion operation; instead, it is guarding against the possibility
that there might be one it hasn't seen.
Can anyone cite some unambigous part of the ARM
that I might have missed that answers this question? If not, has the
committee addressed the question?
--
Joe Buck jbuck@ohm.berkeley.edu
Author: jbuck@forney.berkeley.edu (Joe Buck)
Date: 21 Apr 92 01:24:50 GMT Raw View
Following up my own message:
The code I referred to:
|> class Foo;
|>
|> void bar(Foo*);
|>
|> void bletch(Foo& arg) {
|> bar(&arg);
|> }
compiles without error on g++ 2.1, contrary to claims by its authors that
an error reported in a larger program was correct ARM behavior. g++
apparently allows & on a reference to an incomplete class in some places
but not in others.
Regardless of the behavior of any particular compiler, I'm interested in
clarifications as to whether this code should or should not be accepted.
--
Joe Buck jbuck@ohm.berkeley.edu