Interesting little trick I picked up a while back, been meaning to blog about it. If you're already in the loop, run along.
Prior to enlightenment, I used to write conditionals something like this:
... more specifically:
That's how I'd "say" it, so that's how I wrote it. But is it the best way? I now don't think so. When reviewing other peoples' code (often from C programmers), I've seen "backwards" conditionals.. something like:
Which just sounds weird. Why would you compare a constant to a variable (you'd normally compare a variable to a constant).
So, what's the big deal?
Well, a few months back, I stumbled on an old article about a backdoor almost sneaking into Linux.
Here's the almost-break:
Ignore the constants, I don't know what they mean either. The interesting
current->uid = 0
See, unless you had your eyes peeled, here, it might look like you're trying to ensure that current->uid is equal to 0 (uid 0 = root on Linux). So, if options blah blah, AND the user is root, then do something.
But wait. There's only a single equals sign. The comparison is "==". "=" is for assignment!
Fortunately, someone with good eyes noticed, and Linux is safe (if this had made it into a release, it would've been trivial to escalate your privileges to the root level).. but how many times have you had this happen to you? I'm guilty of accidentally using "=" when I mean "==". And it's hard to track down this bug.. it doesn't LOOK wrong, and the syntax is right, so...
This is nothing new. Everyone knows the = vs == problem. Everyone is over it (most of the time). But how can we reduce this problem?
A simple coding style adjustment can help enormously here.
Consider changing "$var == TRUE" to "TRUE == $var".
sean@iconoclast:~$ php -r '$a = 0; if (FALSE = $a) $b = TRUE;' Parse error: parse error in Command line code on line 1
Of course, you can't ASSIGN $a to the constant FALSE. The same style applied above would've caused a a similar error in the C linux kernel code:
if ((options == (__WCLONE|__WALL)) && (0 = current->uid ))
Obviously, "0" is a constant value--you cannot assign a value to it. The missing "=" would've popped up right away.
Cool. Seems a little awkward at first, but in practice, it make sense.