1

I'm modernizing a legacy project and I enabled -Wconversion flag on Xcode. Now I have a lot of warning like

Implicit conversion changes signedness: 'NSUInteger' (aka 'unsigned long') to 'NSInteger' (aka 'long')

using code like the following while interacting with a UITableView

Item *item = [self.items objectAtIndex:indexPath.row];

row is defined as NSInteger while objectAtIndex: accepts an NSUInteger.

Is there a smart way to fix those warnings?

Lorenzo B
  • 33,216
  • 24
  • 116
  • 190

3 Answers3

5

Either change the type of the row property to return NSUInteger or do this:

Item *item = [self.items objectAtIndex:(NSUInteger)(indexPath.row)];

If you do the latter, you might need to check to make sure row is positive.


Edit

Since the row is a property of NSIndexPath there is clearly a good reason why it might be negative or Apple would have made it an NSUInteger, perhaps if there is no item selected, it is set to -1. So what you should do is make sure that the value of row is not negative and then do the cast above to suppress the warnings, like this:

NSInteger row = indexPath.row
if (row >= 0)
{
    Item *item = [self.items objectAtIndex:(NSUInteger)row];
}
else
{
    // whatever you need to do for no row available
}
JeremyP
  • 84,577
  • 15
  • 123
  • 161
  • Yep! The cast is the correct way but I think I will get crazy. What do you mean *change the type of the `row` property to return `NSUInteger`*? `row` belongs to `NSIndexPath` class in this case. – Lorenzo B Mar 12 '15 at 17:48
  • So, *-Wconversion* is enabled or not in your projects? – Lorenzo B Mar 12 '15 at 17:49
  • @flexaddicted Amended the answer a bit – JeremyP Mar 13 '15 at 11:57
  • Thanks. Are you using *-Wconversion* in your project? Just to know. Yep. The cast is the simplier solution but I think I will go with clang push/pop calls in orders to skip those warnings. – Lorenzo B Mar 13 '15 at 12:11
  • 1
    @flexaddicted Yes, I always turn that one on. They do indicate a real potential problem with your code. If the `row` property is negative, you will get an array bounds exception. – JeremyP Mar 13 '15 at 14:43
2

Usually you shouldn't try to be "smart".

NSUInteger row = (NSUInteger)indexPath.row;
Item* item = self.items [row];
gnasher729
  • 51,477
  • 5
  • 75
  • 98
  • Yep! The cast is the correct way but I think I will get crazy. – Lorenzo B Mar 12 '15 at 17:48
  • So, *-Wconversion* is enabled or not in your projects? – Lorenzo B Mar 12 '15 at 17:51
  • 1
    The warning is here for a reason. If you do a comparison like `indexPath.row < self.items.count-1`, and `items.count` is 0, the unsigned integer integer on the right side will silently underflow (and become `NSUIntegerMax`), so the result of the comparison will be other than you expected. I wasted few hours of my life because of this subtle bug, after that I always turn this warning on. You can take a look on my question on this: http://stackoverflow.com/q/21724824/2128900 – Michał Ciuba Mar 13 '15 at 12:53
0

I kept getting this warning after I upgraded to Xcode 11. Going back to Xcode 10 fixed this.

Bilbo Baggins
  • 3,644
  • 8
  • 40
  • 64