[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