This is essentially a small piece out of a much bigger pie, which is that if you program in languages that allow you to be 'clever' you should use a 'safe subset' of that language where behaviour is both unambiguous and the same across all platforms. This will save you a lot of headaches debugging a program that works fine on a different installation.
There are many other examples of this, for instance always use 'sizeof()' even if you know your storage allocation units, don't rely on the byte order of your words (endian-ness), stick to one statement (explicit or implicit, the example line from the article has two statements).
What makes the example so tricky is that you have to know the innards of the compiler (or at least of the expression evaluator) to be able to correctly predict what that code will do.
Some people think there are bonus points to be had for such 'cleverness' because you only need one line where someone else needs two. There isn't and all it will give you (or, possibly your successor) is a bunch of extra gray hairs.
A similar case can be made for always using brackets, even when they're optional, not using assignments in condtionals and so on.
It's the kind of thing where a junior programmer will go 'oh, cool!', and a seasoned one will go 'oh oh'.
In the case of complicated expressions feel free to add some extra parentheses to make the order of evaluation implicit. They don't cost you anything and they'll allow someone else to read the expression from the inside to the outside instead of from the left to the right and then apply the order-of-evaluation rules.
If you come across:
x = y + z*a + b*d^i++;
And you think it does the same as:
x = y + (z*a) + (b*(d^i)) ;
i++;
Then think again, it is equivalent to:
x = (y + (z * a) + (b*d))^i);
i++;
There is absolutely no penalty for writing it down explicitly.
Sure, some seasoned old hand is going to say, hey, don't you know the expression evaluation rules by heart ? But don't let that intimidate you, that's probably also the person that spends a lot of time in the debugger fixing their extreme cleverness.
The compiler will generate exactly the same code for either the first or the last example (but not the second), there really is 0 penalty, use that.
The compilers might be more helpful, too, by displaying hints or even warnings when the clever code is used. This would not forbid it but would encourage for universally cleaner code.
$ cat foo.c
#include <stdio.h>
int main(int ac, char av)
{
int x = 3;
x = x + x++;
printf("x = %d\n", x);
return 0;
}
$ make foo CFLAGS=-Wall
cc -Wall foo.c -o foo
foo.c: In function ‘main’:
foo.c:5: warning: operation on ‘x’ may be undefined
$ ./foo
x = 7
I don't know as much about C# as I do C or C++ but they both have the concept of sequence points in between which order of operations is undefined behavior. As such I find his specification of order of ops suspicious and makes a stronger argument for explicit statements. However the whole if you don't know what it does then you should be learning not dumbing down the rest of us should apply.
There are many other examples of this, for instance always use 'sizeof()' even if you know your storage allocation units, don't rely on the byte order of your words (endian-ness), stick to one statement (explicit or implicit, the example line from the article has two statements).
What makes the example so tricky is that you have to know the innards of the compiler (or at least of the expression evaluator) to be able to correctly predict what that code will do.
Some people think there are bonus points to be had for such 'cleverness' because you only need one line where someone else needs two. There isn't and all it will give you (or, possibly your successor) is a bunch of extra gray hairs.
A similar case can be made for always using brackets, even when they're optional, not using assignments in condtionals and so on.
It's the kind of thing where a junior programmer will go 'oh, cool!', and a seasoned one will go 'oh oh'.
In the case of complicated expressions feel free to add some extra parentheses to make the order of evaluation implicit. They don't cost you anything and they'll allow someone else to read the expression from the inside to the outside instead of from the left to the right and then apply the order-of-evaluation rules.
If you come across:
And you think it does the same as: Then think again, it is equivalent to: There is absolutely no penalty for writing it down explicitly.Sure, some seasoned old hand is going to say, hey, don't you know the expression evaluation rules by heart ? But don't let that intimidate you, that's probably also the person that spends a lot of time in the debugger fixing their extreme cleverness.
The compiler will generate exactly the same code for either the first or the last example (but not the second), there really is 0 penalty, use that.