94

It matters less whether you are confident in your grasp of the language. What matters more is the grasp of the language of the n00b that follows you. Write your code in the clearest most unambiguous way possible. Extra parenthesis often (but not always) help. Putting only one statement on a line often helps. Consistency in coding style often helps. ...


72

Languages have copied that from C, and for C, Dennis Ritchie explains that initially, in B (and perhaps early C), there was only one form & which depending on the context did a bitwise and or a logical one. Later, each function got its operator: & for the bitwise one and && for for logical one. Then he continues Their tardy introduction ...


32

Yes You should always use parentheses... you do not control the order of precedence... the developer of the compiler does. Here is a story that happened to me about non use of parentheses. This affected hundreds of people over a two week period. Real World Reason I inherrited a main-frame application. One day, out of the clear blue it stopped working. ...


18

Yes, if there are mixed 'and' and 'or'. Also good idea to () what is logically one check. Though best is to use well-named predicate functions and evict most checks and conditions there, leaving if simple and readable.


17

The designers of the Fortress Programming Language did extensive reviews of scientific literature to see how operators are used and what relative precedence they have. Based on those observations, they designed operator precedence in Fortress. This is the only instance I know of where a Programming Language Designer has explicitly written down their ...


14

The parentheses are semantically redundant, so the compiler doesn't care, but that's a red herring--the real concern is programmer readability and comprehension. I'm going to take the radical position here and give a hearty "no" to the parentheses in a AND b OR c AND d. Every programmer should know by heart that precedence in Boolean expressions goes NOT > ...


10

If you need to follow some standard, then follow that standard even if the advice seems suboptimal. Note that many coding standards and guidelines have a specific goal in mind. MISRA is geared towards security, and therefore wants to eliminate any possibly confusing constructs. As operator precedence can sometimes be confused even by experienced programmers, ...


10

There isn't some grand logical scheme, especially in C and the derivatives that kept its order. It's basically a combination of "this feels right" and historical accident. Obviously, you want to keep the precedence of arithmetic operations that you learned in school: * and / before + and -. All the number manipulation should be somewhere in that area. (...


8

As I see it: YES Pros: Order of operations is explicit. Protects you from future developers who don't understand order of operations. YES Cons: May result in cluttered, difficult to read code NO Pros: ? NO Cons: Order of operations is implicit Code is less maintainable for developers without a good understanding of order of operations.


8

When designing a language, you can tweak precedence and other rules to create an elegant experience. Sometimes, not allowing certain constructs can improve readability, without sacrificing much expressiveness. You only loose similarity to other languages, thus making your language harder to learn. You established -x**y == -(x**y). This makes sense, as this ...


7

Two's complement represents numbers in the range -(2**(N-1)) .. (2**(N-1))-1, where N is the number of bits. For example, 16-bit 2's complement represents -32768 .. 32767. If the product of A and B is 32768, the first expression will overflow, because 32768 cannot be represented before being negated, while the second expression will do fine because it ...


5

The first statement (the exceptions) refers to the comma operator, this is (usually) different to commas in function calls. The comma operator is used rarely, but can be used to do things like this: int i,j; /* not comma operator */ for(i=0,j=0; i<10 && j<10; ++i, ++j) /* comma operators */ { doProcWith2Args(i,j); /*not comma operator*/ }...


5

There are two cases to consider: multiplication (including division) and addition (including subtraction). Because floating point numbers are stored in exponential form (i.e as m*2^e), these operations are performed on the mantissa (m) and exponent (e) as separate values, not on the whole numbers involved. Multiplication (basically) involves multiplying the ...


5

I believe the direct answer is simply that functions are not operators. From the page you linked: If the token is a function token, then push it onto the stack. This is all it needs to say, since the function case (prefix to postfix) is much simpler than the operator case (infix to postfix). For the follow-up questions: The notions of precedence and ...


5

Well, I would write your example almost exactly as you stated is the "bad way", because I'm not writing it for me, I'm writing it for the next engineer(s), and they may not have the understanding of the functionality down as much as I do. Let's take the second (simple) example in your last code block: y = ((x * y) + 1); // Some valuable comment here or ...


3

In the absence of any structures being indexed using these variables, which is where prefix and postfix operators really come into their own, I'd suggest that this is a largely academic exercise. Speaking pragmatically; take control of the expression and add brackets to make the order explicit, if only to save your sanity. It also eliminates any ...


3

General case In C#, multiplication and division has a precedence over addition and subtraction. Still, StyleCop, a tool which enforces common style across the codebase with an additional goal to mitigate the risk of bugs introducing by code which may not be clear enough, has the rule SA1407. This rule will produce a warning with a piece of code like this: ...


3

I implemented the asked for "functions in shunting yard" after reading Dijkstra's original thinking (Pages 7-11 in the Algol 60 compiler paper, https://ir.cwi.nl/pub/9251), and needing a robust solution, I did the following: parsing: Push the function descriptor Push a start-of-args left bracket "[" just like his start of subexpression parenthesis. Read a "...


3

There are two different cases to consider, depending on your language syntax. If your language uses parenthesis to indicate function application (eg f(2+1)) then precedence is irrelevant. The function should be pushed onto the stack and popped out after (for the example above, the result is 2 1 + f). Alternatively you can treat the function as a value and ...


3

Legacy, It used to be that in C the non-short circuiting logical operators were the only ones available and then it was logical for them to be after equality. Later the short circuiting were created and the old precedence rule was never changed in the name of backwards compatibility.


3

Are there any arguments in for or against including the extraneous parentheses? Does practical experience suggest that it is worth including them for readability? Or is it a sign that a developer needs to really sit down and become confident in the basics of their language? If no one else ever would have to look at my code again, I do not think I would care....


2

I don't have anything to back it up, but my feeling tells me that the logical and bitwise negation operators (! and ~) are most closely related to the unary minus (-) and should have the same precedence level.


2

When looking for an "industry standard", one might look at the most popular programming languages. However, the problem you are describing occurs only in conjunction with the exponentiation operator. And languages like C, C++, Java, C# these languages don't have this operator, Javascript currently does not have one, but this is going to change (see below). ...


1

Your example don't use unary plus. You use it for string concatenation, and for addition. "6.0+1="+6.0+1 will be evaluated in types as string + number + number. So first "6.0+1" + 6.0 will use + as the string concatenation operator, resulting in a new string: "6.0+1=6.0". Then the same happens with the + 1 at the end, resulting in another string ...


1

Since we know that -> and [] have the same precedence and bind left to right, why is B->Start evaluated before B->data[]. This is a common misconception that just won't die. Precedence and evaluation order are unrelated. Precedence rules tell us what your statement means; which tokens form operands to which operators. It tells us that your code is ...


1

Actually, it doesn't matter whether B->start or B->data is "evaluated" first. The result of interest is address of the referenced element, which is the sum of the base address and the product of the index and the size of the element. The two addends are independent, meaning that the order of their evaluation is irrelevant. The result of the addition is an ...


1

As everyone said, use parentheses everytime it makes the expression more readable. However if the expression is complicated I'd advise to introduce new functions for the subexpressions.


Only top voted, non community-wiki answers of a minimum length are eligible