[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [objc-improvements] RFC: Message passing prototype search cleanup
From: |
Ziemowit Laski |
Subject: |
Re: [objc-improvements] RFC: Message passing prototype search cleanup |
Date: |
Thu, 4 Sep 2003 13:54:27 -0700 |
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