Re: Why does NSArray count return NSUInteger?
Re: Why does NSArray count return NSUInteger?
- Subject: Re: Why does NSArray count return NSUInteger?
- From: Jeffrey Walton <email@hidden>
- Date: Sun, 29 May 2011 18:15:10 -0400
On Sun, May 29, 2011 at 4:04 PM, julius <email@hidden> wrote:
> Hi,
> I have just spent time investigating why
> an if statement involving an [array count] was apparently misbehaving.
>
> The construct was this:
> if(3 < ([zAry count] - 10))
> It delivers a (to me unexpected) result when [zAry count] < 10.
>
> In fact
> if(3 >= ([zAry count] - 10))
> also returns an unexpected result for the same [zAry count] value.
>
> The reason is that [zAry count] returns a result of type NSUInteger!!!!
>
> Thus for this type of comparison I need to coerce the type to NSInteger i.e.
> if(3 < ((NSInteger)[zAry count] - 10))
>
>
> Why might the Cocoa developers have chosen to do this?
> Julius
>
>
> ======
> Here to satisfy possible curiosity is my test code snippet and results
> NSMutableArray * zAry = [[NSMutableArray alloc]init];
> for(NSInteger i = 0; i < 7; i++) {
> [zAry addObject:@"obj"];
> }
>
> NSLog(@"[zAry count] = %d",[zAry count]);
>
> if(3 < ([zAry count] - 9)) {
> NSLog(@"A1: wrong result for: 3 < %d",([zAry count] - 9));
> } else {
> NSLog(@"A2: correct result for: 3 < %d",([zAry count] - 9));
> }
>
> if(3 >= ([zAry count] - 9)) {
> NSLog(@"B1: correct result for: 3 >= %d",([zAry count] - 9));
> } else {
> NSLog(@"B2: wrong result for: 3 >= %d",([zAry count] - 9));
> }
>
> NSInteger zAryCount = [zAry count];
> if(3 < (zAryCount - 10)) {
> NSLog(@"C1: wrong result for: 3 < %d",(zAryCount - 9));
> } else {
> NSLog(@"C2: correct result for: 3 < %d",(zAryCount - 9));
> }
>
> NSUInteger zUInt = 7;
> if (3 < (zUInt - 9)) {
> NSLog(@"E1: wrong result for: 3 < %d",(zUInt - 9));
> } else {
> NSLog(@"E2: correct result for: 3 < %d",(zUInt - 9));
> }
>
> // these produce the required result
> if(3 < ((NSInteger)[zAry count] - 9)) {
> NSLog(@"F1: wrong result for: 3 < %d",([zAry count] - 9));
> } else {
> NSLog(@"F2: correct result for: 3 < %d",([zAry count] - 9));
> }
>
> if(3 >= ((NSInteger)[zAry count] - 9)) {
> NSLog(@"G1: correct result for: 3 >= %d",([zAry count] - 9));
> } else {
> NSLog(@"G2: wrong result for: 3 >= %d",([zAry count] - 9));
> }
>
> 2011-05-29 20:41:19.107 TestIf[4858:903] [zAry count] = 7
> 2011-05-29 20:41:19.110 TestIf[4858:903] A1: wrong result for: 3 < -2
> 2011-05-29 20:41:19.110 TestIf[4858:903] B2: wrong result for: 3 >= -2
> 2011-05-29 20:41:19.111 TestIf[4858:903] C2: correct result for: 3 < -2
> 2011-05-29 20:41:19.111 TestIf[4858:903] E1: wrong result for: 3 < -2
> 2011-05-29 20:41:19.111 TestIf[4858:903] F2: correct result for: 3 < -2
> 2011-05-29 20:41:19.112 TestIf[4858:903] G1: correct result for: 3 >= -2
>
As Kyle said, its the C language - signed values are
promoted/converted (?) to unsigned. So -1 is always greater than 1 (if
you let it happen). Its really the generated CMP instruction which is
bitting you. Cast the unsigned to an NSInteger (be mindful of overflow
first).
The compiler and/or clang should have warned you about it. A clean
compile using -Wall -Wextra is not difficult with Cocoa/Cocoa Touch. I
add the switches under "Other C Flags" (its easier than checking
boxes). Also turn on clang. If you find you have a lot of interfaces
and those interfaces have a lot of unused parameters, add
-Wno-unused-parameter.
Jeff
_______________________________________________
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