implicit conversion loses integer precision 'long' to 'int' - objective-c

I have a problem getting this problem fixed on xcode don't no why it happens it says
implicit conversion loses integer precision 'long' to 'int'
[self newScheduleNotification:[ud objectForKey:dateKey] addNotifKey:[sw tag] ];

This warning appears, if you assign a integer value (L-value) of type long to a variable (R-Value) of type int. This includes passing arguments of type long to parameters of type int. Probably you do that at [sw tag].
"Integer precision lost" means that the long expression delivering the value might have a value that cannot be represented by the int destination.

Change your type for notifKey to NSInteger in newScheduleNotification:addNotifKey:. You're passing it an NSInteger, which is a long on 64-bit, and an int on 32-bit, but your method is asking for an int. Using NSInteger in both places will handle the type for you. You must be on a 64-bit simulator or device. If you ran on a 32-bit sim or device you'll see the warning goes away because then you're passing an int to a method looking for an int.

Related

Why can you declare an NSInteger with a string value?

Why is it that you can do something like this?
NSInteger something = #"something";
It feels weird that this doesn't throw an error and instead returns some number that, in fact, is an NSInteger.
For me it says Incompatible pointer to integer conversion initializing 'NSInteger' (aka 'int') with an expression of type 'NSString *'
I feel, what you get number is memory address of that NSString.
In Languages Like Objective C, When You Define a class or a constant string(What you define like #"something" is a constant string), it will be stored somewhere and the pointer to it will be used. Pointers are 32-bit and 64-bit. 32-bit pointers are 32-bit Integers so they can easily be casted to an integer. So there is no way to throw an error as it is a legal assignment.
it's the same line of code
NSInteger something = [#"something" integerValue];

Xcode warning: Format specifies type 'long' but the argument has type 'int _Nullable'

I get this warning for the following line of code:
NSLog(#"selected segment: %li", _segmentControl.selectedSegmentIndex);
The property selectedSegmentIndex is of type NSInteger.
If I change the format to %i i get the following warning:
Format specifies type 'int' but the argument has type 'long _Nullable'
Are there any new format specifiers for Nullable types or is this just a bug in Xcode 7?
You should type:
NSLog(#"selected segment: %li", (long)_segmentControl.selectedSegmentIndex);
Because NSInteger has a different length in 32 and 64bit architecture. Previously you didn't see the warning, because probably you was compiling only against 64 bit architecture.
I'd also advise to read Apple Article, as there are new specifiers in Xcode 7 (among others nullable and nonnull).
To answer your doubts from the comment, please refer to this Apple document, where they state the following:
Type Specifiers
Script action: Warns about potential problems; may generate false negatives.
Typically, in 32-bit code you use the %d specifier to format int
values in functions such as printf, NSAssert, and NSLog, and in
methods such as stringWithFormat:. But with NSInteger, which on 64-bit
architectures is the same size as long, you need to use the %ld
specifier. Unless you are building 32-bit like 64-bit, these
specifiers generates compiler warnings in 32-bit mode. To avoid this
problem, you can cast the values to long or unsigned long, as
appropriate. For example:
NSInteger i = 34;
printf("%ld\n", (long)i);
Just want to add :
I got this warning "suddenly" even when I did not change the code that made the warning for long time, and I did not understand why it's appear.
The reason : "Generic iOS Device".
when selected device or simulator, the warnings disappear.
still, I add to the NSLog "(long)" to the variables. till then I only had "%ld", that turn the warning no matter what was selected (generic device, real device, simulator)

How to remove 100s of warnings "implicit conversion loses integer precision: 'NSInteger' (aka 'long') to 'int'" I got after updating to arm64?

Problem:
Yesterday I converted a large project of mine to support arm64 and after that I got 500+ warnings at once. About 70% of them are where NSInteger is being assigned to int or vice versa, and remaining are where NSUInteger is formatted in NSString like this:
NSInteger a = 123;
NSString *str = [NSString stringWithFormat:#"Int:%d", a]; //warning: value of 'NSInteger' should not be used as formate argument; add an explicit cast to 'unsigned long' instead.
Now I do know how to adress them manually, but that's a huge task and very laborious.
I'm also aware that I can silence the type mismatch warnings all together, but I don't want to do that. Of course, they're very helpful.
What I've tried:
I've converted [NSNumber numberWithInt:abc]; to [NSNumber numberWithInt:(int)abc]; using find-n-replace. It fixed some.
I've also tried to change all my int properties to NSInteger properties
but it doubled the number of warnings (reached to 900+ count). So I
reverted.
I've also tried to find some regular expression but couldn't find
something suitable to my needs.
Question:
I'm looking for a regular expression or any other workaround somebody has tried which can reduce the amount of work needed to fix them manually.
Thanks in advance.
NSInteger a = 123;
NSString *str = [NSString stringWithFormat:#"Int:%ld", (long)a];
After updating to 64 bit need to do typecast like this((long)a). %d is only for 32 bit range %ld for long integer. For better understanding got through this apple documentation.
https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Cocoa64BitGuide/ConvertingExistingApp/ConvertingExistingApp.html
In case someone else's facing a similar situation, I want to clarify how to deal with it. Although #Raju's answer is suggesting to do it manually (which I wanted to avoid), I found exactly what I needed at the link he shared.
Apple has provided a script for 64bit conversion called ConvertCocoa64, located at/Developer/Extras/64BitConversion/ConvertCocoa64 which not only converts all int to NSInteger it also deals with float to CGFloat conversion, as stated:
It converts most instances of int and unsigned int to NSInteger and
NSUInteger, respectively. It doesn't convert ints in bit-field
declarations and other inappropriate cases. During processing, the
script refers to a hardcoded list of exceptions.
In addition to above conversions it also flags the lines in code which need manual fix. So this might help with the warnings of String Formats.
Please refer to this link for complete details. It not only explains how to use the script but also suggests some very important post 64-bit migration check points.
objective c implicit conversion loses integer precision 'NSUInteger' (aka 'unsigned long') to 'int
Change key in Project > Build Setting "implicit conversion to 32Bits Type > Debug > *64 architecture : No"
Other warning
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
[caution: It may void other warning of 64 Bits architecture conversion].

Set value of a int from an NSarray

how can I set an int to a value from array ?
I try like that:
int counter;
counter = signArr[4];
doesn't work, I get an err " incompatible pointer to integer conversion sending 'int' to parameter of type 'id' "
thank for help :)
From your comment we can guess that the number is boxed in an NSNumber instance. We can test with a log statement (or in the debugger):
NSLog(#"The class is %#", NSStringFromClass[signArr[4] class]));
and then, if it is an NSNumber instance, looking at the methods on offer we can see integerValue which will provide what you're looking for.
The error you saw
incompatible pointer to integer conversion sending 'int' to parameter of type 'id'
tells you that you want an int but that you have an id. You should know that id is the generic pointer type used in ObjC (if you don't you need to go and read the documentation some more) and thus you need to find a way to convert from the object pointer to the primitive int. The first step is finding out what the object class type is and then checking the docs to see what it offers you to help achieve your goal.

Upgrading XCode caused warning for hex Format Specifier

The following line of code:
[colHeader appendFormat:#"%C", 0x2193];
throws this warning:
Format specifies type 'unsigned short' but the argument has type 'int'
This started appearing when I upgraded to Xcode 4.4 (upgraded compiler?). The warning will drive me nuts...any suggestions on how to remove it? Thanks.
Well, the easiest thing is just to cast it, I guess:
[colHeader appendFormat:#"%C", (ushort) 0x2193];
You can specify that a value is unsigned by appending a "u", e.g., 0x2193u. However, the constant will then be an unsigned int, not an unsigned short, so that won't help you here as you would still get a warning.