Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does it make sense for unary operators to be associative?

The C++ operator precedence table from http://en.cppreference.com/w/cpp/language/operator_precedence (I know it's not normative, but the standard doesn't talk about precedence or associativity) marks unary operators as right/left associative.

From a discussion on a different question, I'm left with doubts. Does it make sense for unary operators to be associative?

like image 228
Luchian Grigore Avatar asked Oct 18 '12 18:10

Luchian Grigore


People also ask

Is unary operator right associative?

Because unary operators are right associative the expression *p++ will be evaluated as *(p++) .

What is the associativity of unary operators?

Associativity specification is redundant for unary operators and is only shown for completeness: unary prefix operators always associate right-to-left (sizeof ++*p is sizeof(++(*p))) and unary postfix operators always associate left-to-right (a[1][2]++ is ((a[1])[2])++).

Does unary operator has left to right associativity?

So the operation will be Left-to-Right. Therefore: 10 - 3 equals 7 then 7 - 2 equals 5 Not as given below (Arithmetic operators always Left-to-Right not Right-to-Left) 3 - 2 = 1 then 10 - 1 = 9 This is absolutely wrong. For further details, please check below reference: Precedence and Associativity.

What does it mean for an operator to be associative?

In programming language theory, the associativity of an operator is a property that determines how operators of the same precedence are grouped in the absence of parentheses.


1 Answers

It's just an artefact of the way that the associativity is derived from the grammar.

The reason that addition is left-associative is that one of the productions for additive-expression is additive-expression + multiplicative-expression, with the additive-expression on the left. So when you see:

a + b + c

this must be equivalent to (a + b) + c, because the only way to match the production is with a + b as the additive-expression and c as the multiplicative-expression. a on its own is an additive-expression, but b + c is not a multiplicative-expression and so a + b + c doesn't match the production if we try to take a as the additive-expression.

If you haven't before, I recommend that you read through the "Expressions" chapter ignoring the semantics: look only at the grammar productions. Then you'll see just how it is that precedence and associativity are defined by the grammar. The big trick is that every "high-precedence" type of expression IS-A "lower-precedence" type of expression. So every multiplicative-expression is an additive-expression, but not vice-versa, and this is what makes multiplication "bind tighter" than addition.

Prefix unary operators are defined in the grammar like: unary-expression: ++ cast-expression and so on, with the operator on the left for prefix and on the right for postfix. In other words, we "insert the parentheses" on the left for postfix and on the right for prefix. That is, we can say that the grouping is left-to-right for postfix operators and right-to-left for prefix operators. And indeed the C++ standard says exactly that (5.2/1 and 5.3/1 in C++03). It might be an abuse of terminology or at least a new coinage to refer to this unary grouping as "associativity". But it's not a major one since it's obvious what must be meant.

The only difference here between binary and unary operators is that the syntax would still make sense if the binary operators grouped in the opposite direction, so a - b - c means a - (b - c). It would be surprising but would not otherwise affect the language. With unary operators it would be more than surprising to group !!a as (!!)a, the language would also have to supply a meaning for the sub-expression !!, which currently it doesn't have. A functional language could give it a meaning: !! might mean the function composed from ! and !, i.e. the same operation as static_cast<bool>(), but C++ has no concept of composing functions or operators. The reason C++ doesn't need to supply that meaning is that ! "groups right-to-left". Which (because of the big trick in the grammar) is just another way of saying that !! is not a syntactically correct expression so is never a sub-expression of anything.

So yes, it does make sense to say that prefix operators group right-to-left and postfix operators group left-to-right. But it's also "obvious" that it must be this way around, because of other things we know about the C++ language.

Btw, I think that technically speaking in C++ at least, postfix ++ is not a unary operator. It's a postfix operator. But that really doesn't matter except that it's the terminology in the standard, because obviously it is an operator and it has one operand, so is "unary" in English.

like image 152
Steve Jessop Avatar answered Oct 04 '22 12:10

Steve Jessop