Michel wrote:Here is a little C test. What is the order of precedence for ^,&,| ?
Should one still refrain from using parentheses when using these operators?
In practice, I follow GCC compiler warnings with "-Wall -Wextra". Sometimes it's annoying, but there's always a good reason behind it. For example, when I write
Sure it's annoying, but if someone else reads my code, it stands out more clearly. And simply mistyping '=' instead of '==' is common, and can sometimes lead to painful debugging sessions.
bob wrote:I only do them to suppress warnings. Not because I like the style. I've tried for years to keep warnings out. I've pretty well succeeded, although it seems new warnings come with each new compiler release.
Ok, good point as far as it concerns A || B && C type expressions (I didn't really try, but I immediately believe that those generate gcc warnings without parentheses), but I'm pretty sure some other parentheses can be removed without causing warnings:
lucasart wrote:Sure it's annoying, but if someone else reads my code, it stands out more clearly. And simply mistyping '=' instead of '==' is common, and can sometimes lead to painful debugging sessions.
Exactly, I am not afraid to admit that some of these warnings have uncovered bugs, and certainly those few redundant parentheses can avoid a lot of doubt regarding the original intention of the code if some else (or I myself many months later) looks at the code. If you see while (a = b), you start to wonder whether this was a mistake or intended. If you see while ((a = b)) you know everything is fine.
Precedence relative to << and >> is another thing that I don't want to pain myself too much with. There are more interesting things to concentrate on than slowly training my reflexes by trial and especially error until it becomes second nature to get this always right without any mistakes (while ignoring compiler warnings).
In the while(a=b) case I agree that the warning does regularly help to catch errors, and I usually do oblige the compiler. Although in cases like while(c = getchar()) I would never have any doubt whether it shouldn't have been an ==.
But I do know operator priorities, (also of << >> & ^ and |), and this warning seems to come only for && and ||, where I most-certainly know them.
Michel wrote:Here is a little C test. What is the order of precedence for ^,&,| ?
Should one still refrain from using parentheses when using these operators?
Fresh from university, I would know the precedences and associativity of all C operators by heart. I prided myself for this skill. How silly.
Then come years of working in teams and in industrial environments, where mistakes cost big money. Then you learn that other people should not have to memorise such stupid trivia in order to understand and modify your code. Enter the MISRA rules.
Now I only omit parenthesis for the simple case of "a + b * c", but not for other cases anymore. It doesn't always look pretty, but it is insane to expect the human reader to guess what you mean. I don't want that kind of 'knowledge' anymore.
bob wrote:
"God, grant me the serenity to avoid using parentheses when they are not needed, the courage to use them when they are needed, and the wisdom to know the difference."
Fits for me.
#2. I don't particularly like parentheses. I've had to (been forced to) work with Lisp several times in the past. I consider that a "write-only programming language." It is very difficult to read something where adding an "extra" level of parens is not benign, but actually affects the final results of the expression.
Oh, I used to do that when I first started learning C: Every other control statement in C (if, while...) required parentheses, so having the naked `return value' seemed unnatural at the time. By now I am perfectly used to it and the extra parentheses seem odd.
bob wrote:I only do them to suppress warnings. Not because I like the style. I've tried for years to keep warnings out. I've pretty well succeeded, although it seems new warnings come with each new compiler release.
Ok, good point as far as it concerns A || B && C type expressions (I didn't really try, but I immediately believe that those generate gcc warnings without parentheses), but I'm pretty sure some other parentheses can be removed without causing warnings:
if (!Attacks(tree, to, enemy)
&& (directions[from][to] != check_direction1)
&& (directions[from][to] != check_direction2))
Same remark.
The false assumption you have is that the code was written like that from the beginning. Most likely not. It has evolved over almost 20 years now, and once a pair of parens is "in" they rarely come "out" because that is a good way to introduce bugs I don't want to deal with.
Whether the above were originally written as shown, or whether the tests were rewritten multiple times, I can't say, and I don't really see any good reason to try to trace them back to the earliest version I have, since I don't have the first 2-3 years worth of versions anyway. I will probably fix the last one above in any case since I don't really like the way it reads...
BTW, the last statement I found in GenerateCheckEvasions(), but I can't find the first example. Where, exactly, is that, if you remember?
I have rewritten/cleaned up a LOT of code in the current version (24.0) so it might be long gone, of course.
bob wrote:
"God, grant me the serenity to avoid using parentheses when they are not needed, the courage to use them when they are needed, and the wisdom to know the difference."
Fits for me.
#2. I don't particularly like parentheses. I've had to (been forced to) work with Lisp several times in the past. I consider that a "write-only programming language." It is very difficult to read something where adding an "extra" level of parens is not benign, but actually affects the final results of the expression.
Because I once (early on) used a c compiler that REQUIRED the parens, for reasons unknown. Those have been cleaned up in 24.0 already. I don't remember which compiler, however, it was a LONG time back.