Tuesday, February 20, 2007

Some BOOLs Have All The Luck

ALERT: This post has been proven wrong. It remains here as a badge of shame. Continue reading for entertainment purposes only!

A quick note, since something just bit me in the ass, and some of us dislike unsolicited ass-biting. Disclaimer: I'm using XCode 2.2 and whatever gdb was current then- this may have been fixed since then.

I had a BOOL member/instance variable, we'll call it myBool. I set it like so-
myBool = someInt == someOtherInt;

And all was well in both debug and release targets. Then I changed the scope of the member/instance variable to global, outside of any class, as in-

static BOOL myBool;

After doing so, the boolean expression above evaluated to false/NO, regardless of the values of the 2 ints. I watched it happen in XCode's debugger window, it was awesome.

After several forceful introductions of my keyboard and my forehead, I tried a silly test that shouldn't matter at all, and it worked.

myBool = (someInt == someOtherInt);

I compiled and disassembled both versions of my release and debug targets, hoping for a most excellent blog post, and was greeted with identical code all round. So the problem appears to be that my version of gdb has different rules for evaluating boolean expressions, depending on the scope of the receiver of the expression. Global variables require a parenthesized expression while member/instance variables do not.

One guess who will be parenthesizing more than usual in the future.

And sorry, Wolf. The Rod Stewart reference was too good to pass up :)

Update: Victoria Wang, who I met at PSIG 101, posted an amusing quote about parentheses from one of her 'CIS' professors(Computing and Information Systems?)

"Some teachers go crazy when you use parentheses on an expression that's going to be evaluated first anyway. I don't care. It's like wearing a belt, and suspenders too!"

So, did gdb swipe my belt or my suspenders? And can I set a watchpoint on my fly?

Cheers, Victoria, and thanks to Wolf for the link.

Update 2:
After a restart, Xcode is no longer exhibiting the strange behavior. Maybe something was corrupt, I don't know. Sorry for the false alarm. It is now safe to reenter the building.


Peter Hosey said...

Your version of Xcode (lowercase c) doesn't matter—it's your GCC version that matters. You can check with gcc --version.

And it works in GCC 4.0.1. Are you sure the assignment was executing? You didn't change something else that affected the path of execution, or affected the value of one of the variables?

Blake C. said...

shell> gcc --version
powerpc-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5247)

Thanks for the case correction. But I should note that gcc compiled the same (correct) code in both cases. It was gdb that exhibited the strange behavior-

shell> gdb --version
GNU gdb 6.1-20040303 (Apple version gdb-434)

As for the later questions, nothing was changed except for the parentheses. I'll whip up a test case tomorrow and try to post it somewhere or mail it to you. I haven't yet figured out how to host files from Blogger...

Always good to hear from you, hope all is well :)

Blake C. said...

OK, whatever it was, it went away with a restart. The post has been amended.

Someone said embarassment is good, because it's bad for the ego, and the ego is bad for us. If that's the case, I'm feeling great!

Thank you, Peter.

Marc Charbonneau said...

I've had some similar problems with Xcode, where it doesn't recognize you've modified a file and thus doesn't compile it during the next build. It can cause some confusion before doing a clean/build.

Blake C. said...

Thanks, Marc. That may have been the problem. After hearing Wolf and others praise the power of the 'double broom', I've finally added the 'Clean All' icon to my toolbar :)