C99 associativity for operators - where is it specified?
Asked Answered
H

2

9

In the C99 standard, the expressions allow for precedence and associativity.

Precedence is documented quite well since the order in which the operators appear in the document are of reducing precedence, so function calls come before multiplicative operators which, in turn, come before additive operators.

However, I can't find a definitive description of the associativity, whether it's left or right. This is important since 35/5*2 would be 14 for one variant (35/5)*2 and 3 for the other variant 35/(5*2).

Section 6.5 Expressions /3, footnote 74 state:

The syntax specifies the precedence of operators in the evaluation of an expression, which is the same as the order of the major subclauses of this subclause, highest precedence first.

Within each major subclause, the operators have the same precedence. Left- or right-associativity is indicated in each subclause by the syntax for the expressions discussed therein.

However, taking the multiplicative case, for example:

6.5.5 Multiplicative operators
  Syntax
    multiplicative-expression:
      cast-expression
      multiplicative-expression * cast-expression
      multiplicative-expression / cast-expression
      multiplicative-expression % cast-expression

  Constraints

Each of the operands shall have arithmetic type. The operands of the % operator shall have integer type.

  Semantics

The usual arithmetic conversions are performed on the operands.

The result of the binary * operator is the product of the operands.

The result of the / operator is the quotient from the division of the first operand by the second; the result of the % operator is the remainder. In both operations, if the value of the second operand is zero, the behavior is undefined.

When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded. If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a.

I can see nothing in there that mentions the associativity, nor does there seem to be any default setting elsewhere in the standard.

Am I missing something here?

Heindrick answered 23/2, 2012 at 6:19 Comment(0)
O
10

Operator associativity isn't specified explicitly as “right-associative” or “left-associative”. You deduce it from the grammar. In your example, the multiplicative-expression term refers to itself recursively, and the recursion is on the left-hand side of the operator. That means that a parser encountering a * b * c must parse a * b * c like (a * b) * c, which is left-associative.

The assignment-expression term (6.5.16) has this grammar:

assignment-expression:
    conditional-expression
    unary-expression assignment-operator assignment-expression

So a parser encountering a = b = c has to parse it like a = (b = c), which is right-associative.

Octa answered 23/2, 2012 at 6:23 Comment(4)
Aaahh, I see, it's actually in the grammar rather than the explanatory text. That makes sense. Presumably cast-expression * multiplicative-expression would be right-associative.Heindrick
Correct. I added an example of right-associativity taken from the standard.Octa
Thats what Left- or right-associativity is indicated in each subclause by the syntax in the footnote is trying to say.Casiecasilda
Yes, I do actually see that now that you've mentioned it, @Jesse. Thanks for pointing out that I'm basically an illiterate goat-herder :-)Heindrick
T
3

The grammar itself specifies associativity, by the productions used:

multiplicative-expression:
  cast-expression
  multiplicative-expression * cast-expression

This means that in a * b * c, c must be parsed as a cast-expression, and a * b as one multiplicative-expression, before further parsing of a * b itself. Thus the left-associativity of multiplication is forced into the syntax-tree by the parsing rules.

Travelled answered 23/2, 2012 at 6:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.