Live data from Hacker News

Dennis Ritchie on the priorities of && || vs. == etc. (1982)

lysator.liu.se

51–60 of 178 posts

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#52
post #9

The relative priorities of && vs ||, or & vs |, match the traditional precedence in logical expressions: "and" binds more tightly than "or", just as * binds more tightly than + ("and" is equivalent to * for one-bit values, and "or" is addition modulo 2). So I think that they got this correct. However, the precedence of & vs &&, or & vs ||, etc is a source of problems.

> However, the precedence of & vs &&, or & vs ||, etc is a source of problems. Do you have any examples of this? In my experience you almost always want the bitwise operators to have a higher precedence than the logical operators, as using the result of logical operators as a bitmask makes little sense. Consider e.g. `A & B && C & D`, which currently is equivalent to `(A & B) && (C & D)`, but with reversed precedence…

It usually comes up if the user intended to write && and writes & at one point in an expression, the different precedence can produce an unexpected result. But gcc and clang have warnings for that.

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#53
post #51

Several comments about && and ||. But where does == go?

Lower than either, so you can do logical (or arithmetical) expressions on both sides of ==. Has nothing to do with nature, it's all about pragmatic decisions on how we want it.

Wrong. In C and C++, == has a higher precedence than && and ||, so `A && B == C && D` parses as `A && (B == C) && D`.

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#54

I don't even know the priority between && and ||. If I'm using both, I use parentheses just so it's more explicit. "a && b || c" should flag a linter, IMO, with "(a && b) || c" or "a && (b || c)" being required.

Sorry, but I'm of the exact opposite opinion. If you don't know, learn. It's not hard (as other sibling comments have noted). Code with superfluous parentheses is even more confusing, since I expect them to be present only when overriding precedence. ...and I just realised your username adds some additional irony.

Explicit is better than implicit. I think the real problem is not breaking up complicated expressions. If it's more than just a few pairs of parentheses making it hard to read there's something more wrong there.

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#55
post #44
post #9

The relative priorities of && vs ||, or & vs |, match the traditional precedence in logical expressions: "and" binds more tightly than "or", just as * binds more tightly than + ("and" is equivalent to * for one-bit values, and "or" is addition modulo 2). So I think that they got this correct. However, the precedence of & vs &&, or & vs ||, etc is a source of problems.

& vs && doesn't feel like a problem to me. & vs == is the real problem: `(val & MASK) == CONSTANT` needs parentheses due to this mistake. `a & (b == c)` essentially almost never makes sense (== gives you a boolean, and when dealing with booleans you can use && instead), yet that it what you get by default if omitting the parentheses.

Yes, the latter issue comes up when the user meant to say && but types & instead.

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#56
post #38

Earlier quoted context omitted.

There is: The neutral element for + is 0 ( x + 0 = x for any x ). The neutral element for * is 1 ( x * 1 = x for any x ). Furthermore, you have arithmetic properties like x * 0 = 0 for any x (annulation) or ( x + y ) * z = ( x * z ) + ( y * z ) for any x , y , z (distributivity). Similarly: The neutral element for OR is false ( x OR false = x for any x ). The neutral element for AND is true ( x AND true = x for any x…

I've never heard of saturation arithmetic and now it all makes sense. Otherwise I thought it was more common to think of XOR as boolean addition, and OR would be represented as xy + x + y.

Yes, true and false with AND and XOR form a mathematical ring [0]. Still, OR is also an additive operation. IMO one could give OR and XOR the same precedence.

On the other hand, there is no strict need to have a dedicated boolean XOR operator, as it works the same as = (equals).

[0] https://en.wikipedia.org/wiki/Ring_(mathematics)

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#57

I don't even know the priority between && and ||. If I'm using both, I use parentheses just so it's more explicit. "a && b || c" should flag a linter, IMO, with "(a && b) || c" or "a && (b || c)" being required.

Sorry, but I'm of the exact opposite opinion. If you don't know, learn. It's not hard (as other sibling comments have noted). Code with superfluous parentheses is even more confusing, since I expect them to be present only when overriding precedence. ...and I just realised your username adds some additional irony.

Although I agree, most times where I mix any of these without parentheses I end up having to explain it either in code review or when somebody does a `git blame` a couple months later. Rather than waste everyone's time explaining it, it's easier to just use the parentheses since it's what many/most people expect and everyone else can read it well enough.

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#58
post #52

Earlier quoted context omitted.

> However, the precedence of & vs &&, or & vs ||, etc is a source of problems. Do you have any examples of this? In my experience you almost always want the bitwise operators to have a higher precedence than the logical operators, as using the result of logical operators as a bitmask makes little sense. Consider e.g. `A & B && C & D`, which currently is equivalent to `(A & B) && (C & D)`, but with reversed precedence…

It usually comes up if the user intended to write && and writes & at one point in an expression, the different precedence can produce an unexpected result. But gcc and clang have warnings for that.

The only operators with precedence between & and && are ^ and |, though. In e.g. the expression from the sibling comment, `a & b == c`, writing & or && doesn't make any difference (aside from short-circuiting). I guess it's an issue if you write & instead of && in an expression that also involves a bitwise-OR (or | instead of || in an expression that also involves logical-AND), but that seems quite rare. I expect that reversing the precedence of the bitwise and logical operators would create problems a lot more often.

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#59

I don't even know the priority between && and ||. If I'm using both, I use parentheses just so it's more explicit. "a && b || c" should flag a linter, IMO, with "(a && b) || c" or "a && (b || c)" being required.

The Ada language requires explicit parentheses in the case of a succession of different logical operators precisely to avoid precedence-related bugs. [0]

In the Pony language, any expression where more than one infix operator is used must use parentheses to remove the ambiguity. [1]

The Zig language considered following Pony, but didn't. [2]

[0] http://archive.adaic.com/standards/83rat/html/ratl-03-06.htm...

[1] https://tutorial.ponylang.io/expressions/ops#precedence

[2] https://github.com/ziglang/zig/issues/114

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#60
post #51

Earlier quoted context omitted.

Lower than either, so you can do logical (or arithmetical) expressions on both sides of ==. Has nothing to do with nature, it's all about pragmatic decisions on how we want it.

Wrong. In C and C++, == has a higher precedence than && and ||, so `A && B == C && D` parses as `A && (B == C) && D`.

Wrong? Did'nt ask how C does it and clearly you did not understand my simple comment. Wtf is going on with hn? It's turning into yet another site were kids think they seem smart by intentionally misinterpreting and bickering.
Post reply on HN