Re: why doesn't the compiler complain?
Re: why doesn't the compiler complain?
- Subject: Re: why doesn't the compiler complain?
- From: Greg Parker <email@hidden>
- Date: Mon, 26 Apr 2010 13:22:41 -0700
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 email@hidden Runtime Wrangler
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden