On Apr 26, 2010, at 1:01 PM, Matt Neuburg wrote:
> I am so confused about something in Objective-C that I thought was perfectly
> clear and that I understood perfectly well. Please give me some kind of dope
> slap to get my brain back on track.
> 
> The Objective-C docs say:
> 
> "Methods in different classes that have the same selector (the same name)
> must also share the same return and argument types. This constraint is
> imposed by the compiler..."

Note "imposed" by the compiler, not "enforced". 

The restriction exists because different parameter types can be passed in 
different ways at the machine code level. If the call site uses one set of 
parameter types and the implementation uses another set of types, then you may 
crash or get mangled data. 

On the other hand, sometimes you get mismatched types that are not-unsafe or 
even desirable, thanks to Objective-C's duck-typing ability. So "must" in the 
docs is merely "should", if you're careful.


> I thought I'd test this assertion, and just the opposite seems to be true:
> the compiler isn't imposing any constraints at all. This leaves me confused
> about what the rule is.
> 
> Here's my test:
> 
> - (void) tryme: (NSString*) s;
[...]
> - (void) tryme: (NSArray*) s;
> 
> Those are methods in different classes with the same name but different
> argument types, right? Yet that code compiles just fine. What happened to
> the constraint imposed by the compiler?
> 
> So now let's try actually calling tryme (in yet another class):
> 
>    MyClass* thing = [[MyClass alloc] init];
>    NSString* s = @"Howdy";
>    [(id)thing tryme: s];
> 
> This, too, compiles with no problem. Why is the compiler not complaining
> that tryme: is ambiguous? Isn't that what it's supposed to do? (That is why
> I cast to an id, so that the compiler wouldn't be able to resolve tryme:.)

In this test, the mismatch is an NSString* parameter vs an NSArray* parameter. 
That mismatch is "safe": the compiled code for the call site looks the same 
either way. The compiler does not warn about this by default. 

If you turn on -Wstrict-selector-match for this test, you do get a warning:

    % cc -c test.m
    (no warning)
    % cc -c test.m -Wstrict-selector-match
    test.m: In function ‘main’:
    test.m:30: warning: multiple methods named ‘-tryme:’ found
    test.m:5: warning: using ‘-(void)tryme:(NSString *)s’
    test.m:16: warning: also found ‘-(void)tryme:(NSArray *)s’

The compiler warns more aggressively for mismatches that do affect the call 
site's code. Those are more likely to be actual bugs, rather than correct but 
loosely-typed code. For example, if you change your example's parameter types 
to NSString* vs int, you'll get the warning even without any extra warning 
flags.

    % cc -c test.m 
    test.m: In function ‘main’:
    test.m:30: warning: multiple methods named ‘-tryme:’ found
    test.m:5: warning: using ‘-(void)tryme:(NSString *)s’
    test.m:16: warning: also found ‘-(void)tryme:(int)s’


-- 
Greg Parker      gpar...@apple.com     Runtime Wrangler


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to