views:

582

answers:

17

Should the programmer be aware of operator precedence thoroughly? Using braces to group expressions should be okay, isn't? I always uses braces to be on safer side. And when asked a question on precedence, I cannot answer readily.

+6  A: 

Yes, it's important to understand operator precedence. However, I think there's value in using parentheses to be perfectly clear about your intention. It will help readability and maintainability.

Jon B
A: 

I know the basics (e.g., division and multiplication higher than addition and subtraction), but I would have to look up something more esoteric.

I usually use parentheses to make my intention clear. I think it reads better, and avoids errors due to incorrect assumptions.

duffymo
+1  A: 

It certainly couldn't hurt, and can help you read code with precendence subtleties written by others.

In practice, though, it's probably better not to assume that those maintaining your code will have the same skill, so while should be able to read this code you may not want to write code that takes too much advantage of the interactions. Better to use constructs that are unmistakable, even if it means a few extra parentheses here and there.

Joel Coehoorn
A: 

I think it's important to understand the basic predidence rules. I find knowing the nitty gritty details to be not worth the time. Mainly because any case where predecence is ambiguous can be solved with a simple set of parens. Secondly because not everyone knows them and it's best to make your code readable to the users in your group.

At one time in college, i used to know all of the predence rules by heart. Once I got into the real world I found most people did not know them by heart. If i checked in some valid code which depended upon some predecence rules I consistently got the same feedback "add parens to make it obvious".

JaredPar
+21  A: 

For very common operators - yes, it's worth knowing it. If you put brackets round everything that would otherwise rely on operator precedence, your code would be unreadable (or easily confused with Lisp).

For more obscure operators - I've explicitly avoided learning them. If I start taking too many things for granted that I can't reasonably expect other developers to know, I'll start writing code which I can read easily but no-one else can. The best example is shift operators. I don't even know (for sure - I have an inkling) which of these would be treated the same without the brackets, but I'm absolutely sure which is clearer:

int x = (y << shift) + offset;

or

int x = y << (shift + offset);
Jon Skeet
The shift operator is truly evil. All I know is it's always the opposite of what you had thought when you used it :)
Jon B
Explicitly avoiding knowledge doesn't sound like a good idea to me.
PEZ
@PEZ - does the downvote button work on Jon Skeet's answers? I don't think anyone has tried that yet ;)
Jon B
Knowing more than the next guy, and applying the knowledge, can really confuse the next guy. It doesn't matter whether you know the precedence above, but use the parentheses anyway.
David Thornley
@Jon B - No, it didn't work of course. =)
PEZ
If you're *really* worried about confusing the next guy, then split the expression out into multiple, discreet statements, one per line, with separate result variables for each one. Otherwise, just give the next guy a cheat sheet when he complains about it.
Shog9
PEZ: You'll never know everything. Why do assume the guys maintaining your code will know everthing? I used to know this (shift operator precedance) in c, now - many years later - I just remember it was unintuitive. +1 Jon
Binary Worrier
Put it this way: if I spend time learning the precedence of operators where I wouldn't want to *use* that knowledge, that's time I could have spent learning something else, isn't it?
Jon Skeet
@Binary: Have I said I know everything? I would use parens for the examples above too. It's the avoidance of learning that I'm against.
PEZ
I think what Jon is saying is, "I'm avoiding clever code, and instead writing obvious code".
Paul Nathan
@Jon that is the most counterintuitive reason I have heard not to learn something....but now that you say it, I have to admit that I agree with it. Well put.
Kevin
There's a difference (rather big in my book) between not bothering with learning something and explicitly avoiding it.
PEZ
@PEZ: Maybe you just have a better resistance to the urge to abuse knowledge than I have. Seriously, I do understand what you're saying - but equally "a little knowledge is a dangerous thing" can apply to. There are some useful bits of precedence I know that others may not, (continued)
Jon Skeet
such as "a ?? b ?? c" in C# - but in those cases if a colleague raised it I'd grab a whiteboard and talk to them about, because I think it's worth knowing. Other things, I don't think are worth it - so if I see a table of operator precedence in a book, I'll generally skip it.
Jon Skeet
@PEZ: My brain in finite (increasingly so as I get older), I am not the sponge I was when I was younger and needed to know EVERYTHING about the tools I used. These days I'm still passionate about the work and the tools, but I don't get all the fine detail. There isn't enough time, or organic RAM :)
Binary Worrier
@Jon: Me, too. Or, no, if it's a language new to me I scan it quickly to see if there are any surprises there. "A little knowledge is a dangerous thing" doesn't apply here I think.
PEZ
I also avoid learning (clever) operator precedence. I'd have to learn it and keep it straight for at least four languages. And everyone I work with would have to do it too. There's just more valuable stuff to use that biological RAM for.
David B
I'm probably bad at getting my message through. But let me assure you people that I'm not advocating one should study precedence tables and learn them. My quest is against the avoidance of learning. /Don Quijote
PEZ
i think i agree with Jon. knowing all the precedence rule is useless, because you can always put parentheses, and good compilers warn about missing parentheses anyway. However, some basic knowledge is never bad, like "a " (in c++)
Johannes Schaub - litb
@PEZ: I suspect we actually behave very similarly, but we just express ourselves differently.
Jon Skeet
@Jon S: Yeah, it's probably so.
PEZ
+1  A: 

I'm with you on this one; using braces to make the precedence explicit is always a good idea. It makes your code easier to read, and your intentions are explicit.

With that said, you should know where to look up information on operator precedence, in case you are maintaining others' code.

pkaeding
+1  A: 

You should understand it to be able to read the code written by someone who hasn't used parens everywhere.

I don't think "always-braces" is a good rule of thumb. Code that has too many parens gets harder to read than necessary. Like:

(a * b) + c

is just silly. There's a balance somewhere and the challenge is to find it. Like so many other things it's about applying common sense.

PEZ
+1  A: 

Practically: Not really. If it's so complicated that you have to know operator precedence, you should probably break up the expression into chunks anyway. Also, parenthesis will save you!

Professionally: It doesn't take long to learn the order for your language of choice and can come in handy when reading other people's code. If nothing else, just keep it on a cheat-sheet on your cube wall.

EndangeredMassa
+3  A: 

You should understand it, but you should not assume that others will. I always use parenthesis to make the precedence explicit.

Jim C
+4  A: 

I use a cheat sheet for all but the most common arithmetic operators. If something is the least bit tricky, I use explicit parentheses to make my intentions clear.

The reason I like using a written guide rather than memorizing precedence is that I often work in multiple languages with subtly different rules. Memorizing anything beyond the most common operators can lead to errors when I begin to rely too much on my memory.

Bill the Lizard
A: 

No!

If you are unsure of the precedence then its probable that anyone else reading the code would be liable to interpret it wrongly.

If you are unsure just

 ( .. ) 
the relevent bits of code then there is no ambiguity for you or anyone else.

James Anderson
A: 

There's a third option. Rather than memorizing all those rules, or using parentheses to make sure of everything...

If your expression is so long that it's not clear what happens first, break it up into multiple lines, using temp variables for intermediate results. Then you're introducing clarity without the clutter of parentheses, and you can use descriptive names for the temp variables to make things even more clear.

Kyralessa
A: 

I never have a 100% grip on the precedence rules because I work in several languages (C, C++, perl, bash, and once in a while a dash of TCL/TK.). At various times over the years I've worked with several different assembly languages and a non-conforming compiler or two.

I CAN'T keep the fully detailed precedence rules straight in my head - I have to switch among rule sets too often.

Michael Kohne
+1  A: 

Quick, which has higher precedence in T-SQL: AND versus OR.

SELECT c.Name
FROM [Customer] c LEFT JOIN [Order] o
  ON c.CustomerKey = o.CustomerId
WHERE c.Name like 'B%'
  OR c.Name like 'Z%'
  AND o.CustomerId is NULL

Once you learn the precedence of these operators to the point you rely on that precedence, you're doomed either to:

  • Use them wrong yourself.
  • Suffer the mistakes of others, who will not learn these operators and cannot read your code.
David B
A: 

Yes For:

  • * / + -
  • && || And Or

No/Maybe:

  • << >> & | ^
Michael Buen
+4  A: 

Years ago I saw this precedence table for C:

  • Multiplication and division occur before addition and subtraction.
  • Use parentheses.

That's slightly over simplified, but it has the right idea.

Darron
A: 

It is very very easy to fool yourself when writing a == a & some_flag.

Even if I would suggest not learning precedence rules, using parentheses and temporaries for clarity (remember : code is meant to be read by human beings), sometimes an operator precedence table comes in handy.

Alexandre C.