Objective-C implicit conversion loses integer precision 'NSUInteger' (aka 'unsigned long') to 'int' warning

Objective CCompiler WarningsImplicit Conversion

Objective C Problem Overview


I'm working through some exercises and have got a warning that states:

>Implicit conversion loses integer precision: 'NSUInteger' (aka 'unsigned long') to 'int'

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    @autoreleasepool {
        
        NSArray *myColors;
        
        int i;
        int count;
        
        myColors = @[@"Red", @"Green", @"Blue", @"Yellow"];
        
        count = myColors.count; //  <<< issue warning here
        
        for (i = 0; i < count; i++)
            
        NSLog (@"Element %i = %@", i, [myColors objectAtIndex: i]);
    }
    
    return 0;
}

Screenshot

Objective C Solutions


Solution 1 - Objective C

The count method of NSArray returns an NSUInteger, and on the 64-bit OS X platform

  • NSUInteger is defined as unsigned long, and
  • unsigned long is a 64-bit unsigned integer.
  • int is a 32-bit integer.

So int is a "smaller" datatype than NSUInteger, therefore the compiler warning.

See also NSUInteger in the "Foundation Data Types Reference":

> When building 32-bit applications, NSUInteger is a 32-bit unsigned > integer. A 64-bit application treats NSUInteger as a 64-bit unsigned > integer.

To fix that compiler warning, you can either declare the local count variable as

NSUInteger count;

or (if you are sure that your array will never contain more than 2^31-1 elements!), add an explicit cast:

int count = (int)[myColors count];

Solution 2 - Objective C

Contrary to Martin's answer, casting to int (or ignoring the warning) isn't always safe even if you know your array doesn't have more than 2^31-1 elements. Not when compiling for 64-bit.

For example:

NSArray *array = @[@"a", @"b", @"c"];

int i = (int) [array indexOfObject:@"d"];
// indexOfObject returned NSNotFound, which is NSIntegerMax, which is LONG_MAX in 64 bit.
// We cast this to int and got -1.
// But -1 != NSNotFound. Trouble ahead!

if (i == NSNotFound) {
	// thought we'd get here, but we don't
	NSLog(@"it's not here");
}
else {
	// this is what actually happens
	NSLog(@"it's here: %d", i);

	// **** crash horribly ****
	NSLog(@"the object is %@", array[i]);
}

Solution 3 - Objective C

Change key in Project > Build Setting "typecheck calls to printf/scanf : NO"

Explanation : [How it works]

Check calls to printf and scanf, etc., to make sure that the arguments supplied have types appropriate to the format string specified, and that the conversions specified in the format string make sense.

Hope it work

Other warning

objective c implicit conversion loses integer precision 'NSUInteger' (aka 'unsigned long') to 'int

Change key "*implicit conversion to 32Bits Type > Debug > 64 architecture : No"

[caution: It may void other warning of 64 Bits architecture conversion].

Solution 4 - Objective C

Doing the expicit casting to the "int" solves the problem in my case. I had the same issue. So:

int count = (int)[myColors count];

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmonkeyboyView Question on Stackoverflow
Solution 1 - Objective CMartin RView Answer on Stackoverflow
Solution 2 - Objective CAdrianView Answer on Stackoverflow
Solution 3 - Objective CDarshit ShahView Answer on Stackoverflow
Solution 4 - Objective CVladimir DespotovicView Answer on Stackoverflow