C confusion (probably)


#1

Slightly modified from the book’s example:

[code]- (IBAction)showQuestion:(id)sender
{
NSLog(@“Well, it looks like currentQuestionIndex is… %i”, currentQuestionIndex);

currentQuestionIndex++;  // Out of curiosity I initialized it to -5.  It's now -4.

NSLog(@"After the magic ++ thingy, it looks like currentQuestionIndex is... %i", currentQuestionIndex);

NSLog(@"It looks like [questions count] is... %i", [questions count]); // It's 3.
	
if(currentQuestionIndex >= [questions count]) {
	NSLog(@"(currentQuestionIndex >= [questions count])");
	NSLog(@"currentQuestionIndex = %i", currentQuestionIndex);
	NSLog(@"[questions count] = %i", [questions count]);
currentQuestionIndex = 0;	
}

[/code]

The if(currentQuestionIndex >= [questions count]) returned true! How?

Note that I also changed the == to >= from the book’s example code.


#2

The value returned from -[NSArray count] is an unsigned integer. The compiler will evaluate this statement by assuming both values are unsigned integers, thus converting the currentQuestionIndex to an unsigned integer. Why is this an issue?

All values are represented by binary numbers. When you use a signed integer, the first bit is reserved for a negative flag. If that first bit is 1, the number is negative. Thus, a binary number like so:

10000001

when interpreted as a signed integer is -1. However, unsigned integers use this first bit just like every other bit, by adding 2^n * value to the total value.
Therefore, unsigned integers give up the ability to store negative numbers in exchange for being able to hold much larger numbers. So, the previous binary number is actually 129 when it is unsigned.

Going back to the original problem, the if statement actually evaluates to (UINT_MAX - 4) > 3, which of course, is true.


#3

Thanks, Joe! That perfectly explained my blindspot.

Now I’m treading in fear of all the other stuff I don’t know about C compilers. :slight_smile: