Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparison of integers of different signs warning with Xcode

I use an open source to build my project. when I add EGOTextView to the project, it has Semantic Issues like:


Comparison of integers of different signs: 'int' and 'NSUInteger' (aka 'unsigned long')
Comparison of integers of different signs: 'NSInteger' (aka 'long') and 'NSUInteger' (aka 'unsigned long')

For example in source code:


     for (int i = 0; i &lt lines.count; i++)//lines is an array

I notice the project has build configure file which includes:

// Make CG and NS geometry types be the same. Mostly doesn't matter on iPhone, but this also makes NSInteger types be defined based on 'long' consistently, which avoids conflicting warnings from clang + llvm 2.7 about printf format checking

OTHER_CFLAGS = $(value) -DNS_BUILD_32_LIKE_64

According to the comments, I guess it causes the problems. However, I don't know the meaning for this OTHER_CFLAGS setting. And I also don't know how to fix it so that it can avoid the semantic issues.

Could any one help me?

Thanks!

like image 799
scorpiozj Avatar asked Dec 02 '11 02:12

scorpiozj


4 Answers

Actually, I don't think turning off the compiler warning is the right solution, since comparing an int and an unsigned long introduces a subtle bug.

For example:

unsigned int a = UINT_MAX; // 0xFFFFFFFFU == 4,294,967,295 
signed int b = a; // 0xFFFFFFFF == -1

for (int i = 0; i < b; ++i)
{
    // the loop will have zero iterations because i < b is always false!
}

Basically if you simply cast away (implicitly or explicitly) an unsigned int to an int your code will behave incorrectly if the value of your unsigned int is greater than INT_MAX.

The correct solution is to cast the signed int to unsigned int and to also compare the signed int to zero, covering the case where it is negative:

unsigned int a = UINT_MAX; // 0xFFFFFFFFU == 4,294,967,295 

for (int i = 0; i < 0 || (unsigned)i < a; ++i)
{
    // The loop will have UINT_MAX iterations
}
like image 83
j b Avatar answered Nov 18 '22 18:11

j b


Instead of doing all of this strange type casting all over the place, you ought to first notice why you are comparing different types in the first place: YOU ARE CREATING AN INT!!

do this instead:

    for (unsigned long i = 0; i < lines.count; i++)//lines is an array

...and now you are comparing the same types!

like image 45
i.am.charlie Avatar answered Nov 18 '22 18:11

i.am.charlie


The configuration option you're looking at won't do anything about the warning you quoted. What you need to do is go into your build settings and search for the "sign comparison" warning. Turn that off.

enter image description here

like image 4
SSteve Avatar answered Nov 18 '22 20:11

SSteve


Instead of turning the warnings of you can also prevent them from occurring.

Your lines.count is of type NSUInteger. Make an int of this first, and then do the comparison:

int count = lines.count;
for (int i = 0; i < count; i++)
like image 3
Brabbeldas Avatar answered Nov 18 '22 18:11

Brabbeldas