[objc-improvements] RFC: Message passing prototype search cleanup
Ziemowit Laski
zlaski@apple.com
Thu Sep 4 20:54:00 GMT 2003
Hi Alex,
See comments below.
On Wednesday, Sep 3, 2003, at 18:42 US/Pacific, Alexander Malmberg
wrote:
> First, the compiler will search for a prototype based on the type of
> the
> receiver (which may include a known class, and may include a list of
> protocols, or may be nothing if the type is 'id' or 'Class').
>
> If exactly one prototype is found, it is used.
>
> If more than one prototype is found, one of them will be picked
> "randomly" (in practice, the search is done in a specific order, so it
> isn't really random; I don't think we want users to rely on that,
> though). This is ugly from some povs, but it's compatible with previous
> versions of gcc, and it does the right thing in most cases (when there
> are slight prototype mismatches).
If you can find a way to conditionalize this behavior (e.g., on
'-Wcheck-conflicting-prototypes'
or some such), that's great. A flag will be needed, though, because
Apple will most likely
turn it off by default. :-(
>
> If more than one prototype is found, the fallback prototype is used,
> but
> people do not seem to like this change.
Well, I like it :-), since it makes the failure mode very predictable
(as I've
elaborated previously).
> Earlier versions would pick one
> randomly (but also had problems checking prototype equality, and thus
> wouldn't detect all conflicts).
>
> (Since the code for this has now been cleaned up, I could fairly easily
> change the behavior in any of the cases, if we can agree on what we
> should change it to. :)
>
>
> * When searching for a prototype for a receiver with a known type, the
> search will not stop once it's found a prototype. Instead, it will
> continue in order to catch any conflicting prototypes.
>
> I guess this will be controversial, but IMHO, this is the right thing
> to
> do. In GNUstep, this triggers in five basic cases. One is an obvious
> unintended mismatch, one is a real library issue (after seeing the
> warning, constructing a test case that caused a crash was trivial), and
> one looks like a conflict with a really old compatibility method. I
> have
> not looked closely at the remaining two yet.
>
> Fred Kiefer said in one of the discuss-gnustep threads:
>> Even one correctly reported error would make this change worthwhile.
>
> and I'm inclined to agree.
>
>
> * When searching for a prototype for a class object with a known type,
> and the class is a root class, and we're in an @implementation for that
> class, and a matching instance method is found in the local
> implementation, it will now be "found". This matches what the runtime
> will do.
Good. :-) Thanks for catching this corner case; it hasn't occurred to
me.
>
>
> * When searching all known prototypes, instance methods of root classes
> are included in the class methods. This matches what the runtime will
> do.
Ditto.
>
>
> * Warnings will now use a descriptive name of the type instead of just
> the class name or "not implemented by protocols". Eg.:
>
> "receiver of type `SomeClass <SomeProtocol>' may not respond to ..."
>
> This allows developers to know exactly what the compiler is checking
> against, and makes all the 'may not respond to...' warnings consistent.
That's great also; thanks.
>
>
> * If a message is sent to a receiver with a type we have not seen an
> interface for, a warning is issued:
>
> "no interface seen for `SomeClass'"
>
> Fairly often, I've spent time checking for typos and reading headers
> and
> documentation trying to figure out why the compiler doesn't think some
> class implements a method before realizing that I'd just forgotten to
> include the header. This warning should put an end to that. :)
Our resident NeXT-ies hate it when the ObjC compiler throws new
warnings at them,
but in this particular case I think that they will see the light. :-)
> +
> + /* Search for a suitable prototype. If we can't find one, we use our
> + fallback prototype: id (*)(id,SEL,...).
> +
> + First we check if the type information known for the receiver
> gives any
> + prototypes. If this gives us a unique prototype, we use it. If
> it gives
> + several prototypes, we warn and use one of them "randomly" (we
> use the
> + first one we find, so it's actually well defined; however, we
> don't
> + want users to rely on this).
Before we started messing with things, the compiler would actually pick
the _last_ prototype
seen, since it simply reached into the appropriate bucket in the hash
table (and we prepend
things to buckets rather than appending them). Has this been changed?
> + warning ("(When multiple prototypes are found for a receiver type,
> one");
> + warning ("of them will be picked randomly (but
> deterministically).)");
You know, this message is probably more confusing than any of the
previous candidates. :-) :-)
At this point, I'm really inclined to say that we should go back to the
original warning
behavior: We found multiple signatures, we'll be _using_ such-and-such,
although we also found
this, this and that. :-) At the end of that diatribe, we could perhaps
issue a one-time warning
that the user may want to cast the message receiver to the desired type
to avoid all the madness.
What do you think?
--Zem
--------------------------------------------------------------
Ziemowit Laski 1 Infinite Loop, MS 301-2K
Mac OS X Compiler Group Cupertino, CA USA 95014-2083
Apple Computer, Inc. +1.408.974.6229 Fax .5477
More information about the Gcc-patches
mailing list