Thursday, July 15, 2010

Objective-C MIN and MAX #define wonkiness

Here’s a little odd thing I discovered when trying to use the MIN and MAX macros defined in NSObjCRuntime.h.  I had the following code (simplified):

const int MAX_OBJECTS = 10;
int numObjectsToRemove = MAX(0, myObjectArray.count - MAX_OBJECTS);

Let’s say myObjectArray.count is 1.  What would you expect numObjectsToRemove to become?

0, right?  Because (myObjectArray.count – MAX_OBJECTS) == (1 – 10) == –9, and 0 is clearly greater than –9.  But you’d be wrong.  And so was I.

You see, apparently, since the count member of NSArray is an unsigned int, the entire expression gets treated like an unsigned int.  So, since –9 in unsigned form is actually a very large number, it’s considered greater when compared to 0.  But as if that wasn’t bad enough, when it gets assigned to numObjectsToRemove, it gets treated like a normal signed int again, so its value becomes –9 again.  And you’re left wondering why –9 is considered greater than 0.

The simple fix is to force the macro to treat the whole expression like an int with a simple cast:

int numObjectsToRemove = MAX(0, (int)myObjectArray.count - MAX_OBJECTS);


Unknown said...
This comment has been removed by the author.
Unknown said...

i just had this exact same problem. did a quick google search and found your page as the first result. you probably saved me a few days hitting my head against a brick wall. thanks!

Shai Ohev Zion said...

Thanks, it helped me too!