1

In a expression like "10 - 3 - 2", it's easy to understand why - and + operators are left associative. To match mathematical convention and have 5 instead of 9 as the result. As I understood it, associativity means the order when some operators have the same precedence level.

But what relevance does this have with unary operators? I don't get why an unary operator has associativity.

Note: The question is about general programming, but if you have to answer in a language dependent manner C is preferred.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Insignificant Person
  • 863
  • 2
  • 10
  • 24
  • See http://stackoverflow.com/questions/12961351/does-it-make-sense-for-unary-operators-to-be-associative (not a duplicate, because that is for C++, and the explanation doesn't seems to be "so much good", but it still seems to be "good enough") – xanatos May 09 '15 at 14:50

2 Answers2

1
**Arithmetic Operators** (Left-to-Right)
+   Additive operator (a + b)
-   Subtraction operator (a - b)
*   Multiplication operator (a * b)
/   Division operator (a / b)
%   Remainder operator (a % b)

**Unary operators** (Right-to-Left)
+   Unary plus operator; indicates positive value (numbers are positive without this, however) 
-   Unary minus operator; negates an expression
++  Increment operator; increments a value by 1
--  Decrement operator; decrements a value by 1
!   Logical complement operator; inverts the value of a boolean

But when we consider unary for example:

a = +1
a= -1
a++
a-- etc

What you mentioned here with 10 - 3 - 2 will not be taken into unary operation.

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 the below references:

  1. Precedence and Associativity
  2. Assignment, Arithmetic, and Unary Operators (I'm not much in touch with the C language. But operators are common.)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Estimate
  • 1,421
  • 1
  • 18
  • 31
0

Unary operators don't have associativity, really. At least, not as individual operators. As you say, it's impossible for a unary operator to compete with another instance of itself for the same operand; that can only happen with a binary operator.

On the other hand, the grammatical definition of associativity doesn't just apply between two identical operators. It applies between two operators of the same class. For example, + and - associate mutually, since they both have the same precedence.

Postfix operators including, for example, array subscription and function application) normally associate more tightly than any other operator, including prefix operators. We could annotate that by putting postfix operators in a higher precedence level, or we could annotate it by putting prefix and postfix operators in the same precedence level, and then saying that that precedence level associates to the right.

Both of those descriptions would explain why *f() means "dereference the result of calling f" —*(f())— and not "call the function referenced by what f points at" —(*f)().

Personally, I find it more intuitive to put postfix operators in a different precedence level than prefix operators, and prefix operators in their own precedence levels as well. But the original precedence declaration syntax for yacc did not provide a declaration for precedence levels without associativity. (%nonassoc is different; it prevents chaining, which actually modifies the grammar.) So you had to declare unary operators as %left or %right. Of those two choices, %right makes more sense, because postfix operators (usually) associate more strongly than prefix operators. So that's the usual style. But it's really not very clear.

Bison does allow you to declare a precedence level without associativity, using the %precedence declaration. That's handy for unary operators. But many other yacc-based parser generators do not provide this feature, so you'll still often see unary operators declared with %right.

rici
  • 234,347
  • 28
  • 237
  • 341