Code: Select all
// I dislike this for a reason
if (foo & bar)
{
something = 42;
}
// prefering this instead
if (foo & bar) {
something = 42;
}
There is a very specific reason. Consider this code I just lifted from my kernel:
Code: Select all
// detect IMPS/2 wheel mouse
console_mouse_imps2 = 0;
// set sample rate 200, then 100, then 80, then get ID
if(KBD_write_aux(0xF3) || KBD_wait_ack()
|| KBD_write_aux(200) || KBD_wait_ack()
|| KBD_write_aux(0xF3) || KBD_wait_ack()
|| KBD_write_aux(100) || KBD_wait_ack()
|| KBD_write_aux(0xF3) || KBD_wait_ack()
|| KBD_write_aux(80) || KBD_wait_ack()
|| KBD_write_aux(0xF2) || KBD_wait_ack()) return -1;
{
int id = KBD_read();
if(id < 0) return -1;
if(id == 3) {
console_mouse_imps2 = 1;
}
}
Now, if you quickly browse the source, and know that brace style is always to open blocks for if/for/while/switch statements on the same line, then you immediately know that the block in the above example has nothing to do with the if-statement.
But, if we use the other convention, one needs to scan the big if-statement to see whether there's a semicolon at the end, or if the block is part of the statement.
Some could argue that such big statements aren't good style, but I disagree: in the above example, if any of them fails, it's handled exactly the same, so writing separate conditionals would be needless duplication of code. But that's not all. It's very common that you only have one or two conditions, but the conditions themselves include enough operators, casts and levels of indirection, that you have to split the condition on two lines, or make it very wide (I'm one of those who dislike source that's much wider than 80 characters). When the lines don't align nicely, it's even more work to figure out whether there's a semicolon at the end.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.