Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSUInteger should not be used in format strings?

Tags:

objective-c

Here's my code in all it's glory:

[NSString stringWithFormat:@"Total Properties: %d", (int)[inArray count]];

Which gets me an Xcode 5.1 warning:

Values of type 'NSUInteger' should not be used as format arguments; add an explicit cast to 'unsigned long' instead

Ok so I'm confused. The value really is a 32-bit int, and I cast it to a 32-bit int. So what is this NSUInteger it's complaining about (the count I assume) and why doesn't this cast fix it?

like image 511
Maury Markowitz Avatar asked Mar 26 '14 19:03

Maury Markowitz


3 Answers

It is also possible to use the "z" and "t" modifiers for CPU-independent format strings, e.g.

NSInteger x = -1;
NSUInteger y = 99;
NSString *foo = [NSString stringWithFormat:@"NSInteger: %zd, NSUInteger: %tu", x, y];
like image 30
Nick Lockwood Avatar answered Oct 09 '22 13:10

Nick Lockwood


NSUInteger and NSInteger are different lengths on 32-bit (int) and 64-bit (long). In order for one format specifier to work for both architectures, you must use a long specifier and cast the value to long:

Type    Format Specifier    Cast
----    ----------------    ----
NSInteger    %ld            long
NSUInteger   %lu            unsigned long

So, for example, your code becomes:

[NSString stringWithFormat:@"Total Properties: %lu", (unsigned long)[inArray count]];

There is very little work to do, really, because Xcode's Fix-It feature will do this for you automatically.

like image 138
matt Avatar answered Oct 09 '22 13:10

matt


The underlying type of NSUInteger changes based on the platform: it is a 32-bit unsigned integer on 32-bit platforms, and a 64-bit unsigned integer on 64-bit platforms.

In the Platform Dependencies section on of the String Programming Guide Apple suggests that you do the following:

To avoid the need to use different printf-style type specifiers depending on the platform, you can use the specifiers shown in Table 3. Note that in some cases you may have to cast the value.

For NSUInteger use format %lu or %lx, and cast the value to unsigned long.

Hence your code needs to be changed as follows to avoid the warning:

[NSString stringWithFormat:@"Total Properties: %lu", (unsigned long)[inArray count]];
like image 9
Sergey Kalinichenko Avatar answered Oct 09 '22 13:10

Sergey Kalinichenko