[objc-improvements] Merging back to mainline

Steve Naroff snaroff@apple.com
Sun Sep 7 00:19:00 GMT 2003


> Yes (or 'Class'), although a suggestion has been made on the list that 
> the check for multiple methods could/should always be made.  For 
> example, if your receiver is of type 'id<Foo, Bar>', you're sending a 
> message 'foo', protocol Foo has '-(void)bar' and protocol Bar has 
> '-(int)bar'.  Currently, the compiler will use the signature from 
> protocol Foo and stop.  (This implies that 'id<Foo, Bar>' is not quite 
> the same as 'id<Bar, Foo>', intentionally or not).
>

I agree...the compiler needs to be consistent (and not "stop"). If Foo 
and Bar have conflicts, then the compiler needs to warn.

This is a simple bug to fix.

> Interestingly, your example shows precisely the kind of bad things 
> that can happen. :-)

That is why I picked it.

> What if you're trying to do the following?
>
>   obj2 = [obj bar];
>
> The compiler will die with a hard error, since you've (incorrectly) 
> picked a 'void' return type.

The compiler on my machine doesn't crash.

I still don't see the general problem or point you are making.

> Another, more subtle example is the following:
>
>> xx.m: In function `main':
>> xx.m:20: warning: multiple declarations for method `bar'
>> xx.m:6: warning: using `-(id)bar:(float)'
>> xx.m:12: warning: also found `-(id)bar:(int)'
>
> and suppose you have '[obj bar:123]', and really are calling 
> `-(id)bar:(int)'.  But because you're using the `-(id)bar:(float)' 
> signature, the compiler will provide int->float conversion behind your 
> back, and you'll be mystified as to why your parameter gets garbled 
> during the call.  There are many scenarios similar to this one; if 
> users are more lucky they'll get mysterious warnings/errors about 
> incompatible argument type conversions.

This isn't a subtle problem at all. The compiler is telling you exactly 
what it is doing (which as you say might not be what is intended). It 
is saying there is an ambiguity that it is incapable of understanding.

This is why it is a warning!!! If you don't want the parameter garbled, 
then you should use stronger typing (by changing the declaration or 
casting at the call site).

Here is the "culture clash" that I think I am hearing...you think it is 
objectionable to generate "bad code" for such cases. The only case I 
consider bad is if the compiler generates bad code *without* warning 
you that it is confused (or doesn't know that it is confused). Are 
there such cases? (aside from the composite protocol example mentioned 
above...)

Here is an analogy...sending a message to a method that does not 
exist...in ObjC this is an easy mistake to make...in C/C++ it is 
rare/impossible.

Summary: Supporting dynamic typing atop C has some pitfalls. The design 
of Objective-C is to enable tight integration with C basic types and 
warn if there are confusions. Other design points are:

#1: Force all arguments and return types to be objects. This path was 
not taken for many reasons.
#2: Force all objects to be strongly typed. This path was not taken 
because we support frameworks that benefit from not having strong 
typing. In fact, Objective-C dynamic typing was one of the key reasons 
NeXT decided to use it over C++ in '86.

One potential way to help with the problem I think you are talking 
about is to have a switch that considers some of these cases hard 
errors. Given the existing code base, I wouldn't feel comfortable 
making this the default, however it might be a handy tool to help 
tighten up code that suffers from such ambiguities.

I suggest we get together on Monday and discuss these issues face to 
face.

snaroff

On Friday, September 5, 2003, at 04:54 PM, Ziemowit Laski wrote:

> On Friday, Sep 5, 2003, at 15:28 US/Pacific, Steve Naroff wrote:
>
>> Zem,
>>
>> What is the disagreement about the handling of conflicting method 
>> signatures?
>>
>> As you know, this is only a problem when using anonymous types (i.e. 
>> "id").
>
> Yes (or 'Class'), although a suggestion has been made on the list that 
> the check for multiple methods could/should always be made.  For 
> example, if your receiver is of type 'id<Foo, Bar>', you're sending a 
> message 'foo', protocol Foo has '-(void)bar' and protocol Bar has 
> '-(int)bar'.  Currently, the compiler will use the signature from 
> protocol Foo and stop.  (This implies that 'id<Foo, Bar>' is not quite 
> the same as 'id<Bar, Foo>', intentionally or not).
>
>> Since using anonymous types with multiple method signatures is 
>> ambiguous, the only thing the compiler can do is pick one (the first 
>> one it encounters is as good as any), warn, and make it clear which 
>> version was chosen.
>>
>> [steve-naroffs-Computer:~] snaroff% cc -c xx.m
>> xx.m: In function `main':
>> xx.m:20: warning: multiple declarations for method `bar'
>> xx.m:6: warning: using `-(void)bar'
>> xx.m:12: warning: also found `-(float)bar'
>
> Interestingly, your example shows precisely the kind of bad things 
> that can happen. :-)  What if you're trying to do the following?
>
>   obj2 = [obj bar];
>
> The compiler will die with a hard error, since you've (incorrectly) 
> picked a 'void' return type.  This was the subject of a Radar (among 
> many others pertaining to messaging) that I fixed.
>
> Another, more subtle example is the following:
>
>> xx.m: In function `main':
>> xx.m:20: warning: multiple declarations for method `bar'
>> xx.m:6: warning: using `-(id)bar:(float)'
>> xx.m:12: warning: also found `-(id)bar:(int)'
>
> and suppose you have '[obj bar:123]', and really are calling 
> `-(id)bar:(int)'.  But because you're using the `-(id)bar:(float)' 
> signature, the compiler will provide int->float conversion behind your 
> back, and you'll be mystified as to why your parameter gets garbled 
> during the call.  There are many scenarios similar to this one; if 
> users are more lucky they'll get mysterious warnings/errors about 
> incompatible argument type conversions.
>
> For the same reason, it wrong for the compiler to pick a method 
> signature out of a hat if no methods matching the receiver type and/or 
> protocols are found.
>
> Warning about multiple signatures is one thing; however, I believe 
> that the compiler should be able to gracefully pick up and continue 
> from that point.  My proposed solution is to use the generic IMP 
> signature whenever there are multiple methods found (or if there are 
> NO methods found, which makes the failure mode much more consistent 
> and easy to understand).
>
> --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