This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [objc-improvements] Merging back to mainline


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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]