The facts
This is a very similar question to this one, but here I am talking about a more general case the MISRA-C3 Rule 5.0.2 or the SEI CERT C EXP00-C rule (more permissive).
Within MISRA-C3 I shall use parentheses to avoid implicit operator precedence. So the following code is correct, but to my eyes very boilerplate:
if ((((x * y) + 3) > z) && ((w - 1) <= (42 + (x / (y + z)))))
Note: as I was writing this expression I had to copy/paste it in my code editor to fix the missing parenthesis because it got too cumbersome.
As an experienced programmer I would only use parenthesis for non-obvious precedence that may depend on the programming language I use. The C Operator Precedence Table may not be easy to learn, especially for new C programmers and sometime even for my self when I am tired by hours of programming in the middle of the night.
My rule of thumb is:
Parenthesis shall be used for explicit operator precedence with all operators except the logical and (
&&
) and or (||
), and the 4 basic operations (* / + -
).
The above expression can therefore be simplified like this:
if ((x * y + 3) > z && (w - 1) <= (42 + x / (y + z)))
The latter expression looks much easier to read and I can see at a glance if I am missing a parenthesis.
Moreover, as the equal (=
) operator also falls under the MISRA rule. Developers should also write z = (a * b)
and not z = a * b
.
The story behind
I am working in a company where the developers are far from experienced in C programming despite they all do C programming for more than 10-15 years. They keep adding useless comments x = 2; // Assign x with 2
everywhere and claims the first expression I wrote is much more readable because no human can learn by heart the operator precedence. So they usually use comments, parenthesis or forward declaration everywhere rather than using their common sense to keep the reading flow clear and understandable.
I was trying to teach them the beauty of programming where the programmer has to tell a story and keep the flow crystal clear by avoiding useless things they put everywhere because once someone told them to do so.
Today I am questioning myself and wondering if I am right or wrong about this parenthesis thing. Perhaps the first expression is more understandable than the second one for most people.
Examples
if ((i > LENGTH) && (((a * b) + c) > (d + e))) // Bad
if (i > LENGTH && a * b + c > d + e) // Good
y = ((x * y) + 1); // Bad
y = x * y + 1; // Good
The question
Is my rule of thumb (yellow box above) a good rule? The MISRA C3 Rule 5.0.2 is only advisory and CERT-C is more into my direction.