[Top][All Lists]

[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


* 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?

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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]