-1

I'm learning C programming in university, and for a quiz the question above came. I would like to understand how it will execute. Does it have something to do with the order of precedence?

enter image description here

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
Bigaku Acedia
  • 11
  • 1
  • 2
  • 5
    IMHO This is a useless question and a useless answer to know. Let me explain. You should never ever write this kind of code, even if you understand it. It's too confusing and obfuscated for no reason or gain. For the same reasons this code ideally should not exist. Ok, but what if you encounter this code, after all the world is not ideal. For these cases all you need is to **know how to read the C precedence table** to figure out what it means. That is indeed a skill you need to develop. Knowing by heart the answer to this: not in the slightest. – bolov Jun 13 '21 at 00:25

2 Answers2

3

Yes it does, but that's only half the story.

To solve this one, you need to know two things:

  • the operator precedence of += and |=

  • if these are the same, the associativity of these operators (left-to-right or right-to-left)

Fortunately, there is a table at cppreference.

This tells us that:

  • both += and |= have the same precedence

  • their associativity is right-to-left

The answer to the quiz (as shown in your screenshot!) is therefore a += (b |= c), that is to say
b |= c is evaluated first and the result is then added to a.

But, as bolov points out, any self-respecting programmer would, at minimum, put the brackets in for you, or (ideally) code this as two separate statements.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • "precedence" refers to operator associativity, not order of operations. The precedence means that the operands of `+=` are `a` and `(b |= c)`. There is no requirement for `b |= c` to run first; operands of assignment operators are *unsequenced*. The compiler may update `a` before updating `b` ; and the three expressions `a`, `b`, and `c` could be evaluated in any order. – M.M Jun 13 '21 at 01:30
  • @M.M No, *associativity* refers to associativity, and *precedence* refers to the order of operations. Look at the table linked in this answer: it specifies both precedence levels and associativity. For any two operations in the same expression, the one with the smaller value in the precedence column is executed first. `a & b ^ c` will first evaluate `a & b` and then the result with `^ c` because `&` comes before `^` in the table. – Caleb Jun 16 '21 at 13:59
  • @Caleb Your comment is completely incorrect, sorry – M.M Jun 16 '21 at 20:38
  • @M.M Citation needed. Here's one that supports my view: [*In mathematics and computer programming, the order of operations (or operator precedence) is a collection of rules that reflect conventions about which procedures to perform first in order to evaluate a given mathematical expression.*](https://en.wikipedia.org/wiki/Order_of_operations) Alternatively, give an example in which an operator of lower precedence is evaluated before one of higher precedence. – Caleb Jun 16 '21 at 22:02
  • @M.M See also K&R, 2nd ed., pg 52: "Table 2-1 summarizes the rules for precedence and associativity of all operators...rows are in order of decreasing precedence..." – Caleb Jun 16 '21 at 22:09
  • @Caleb comments are not the place for this discussion, try reading the standard or searching SO for other upvoted Q/A on the topic of precedence in C. E.g. https://stackoverflow.com/questions/5473107/ – M.M Jun 17 '21 at 01:13
  • @M.M AFAIK in common American English usage, *order of operations* and *precedence* both refer to the set of rules that we use to determine the order in which to apply *operators* of *different* precedence. *Order of evaluation*, as discussed in the Q you linked, is somewhat different and refers to the order in which subexpressions are evaluated. It's true that given `a*b+c`, c can be evaluated before `a` or `b` or even `a * b`. However, `+` cannot be applied before `*`, and it's precedence that tells us that. Associativity tells us how to apply operators of the *same* precedence level. – Caleb Jun 17 '21 at 03:59
  • @Caleb in programming, "precedence" has a different meaning to common American English usage. The C Standard does not even mention precedence at all, it is a term used by teaching materials to explain the language grammar in a human-friendly way. In the Standard there is the language grammar, and rules about evaluation order. The language grammar tells us that the expression `a*b+c`, is a `+`-expression with subexpressions `a*b` and `c` , and this analysis is what "precedence" means in programming. The rules about evaluation order are separate to the language grammar . – M.M Jun 17 '21 at 05:21
  • `+` can be applied before `*`, e.g. in `a() + b() + c() * d()`, the four functions can be called in any order, and then the result of the first two added. This is already covered well in the answers to the question I linked (you should read all of the answers, not just the top one, as they explain very clearly). Glad to see you have now backtracked your claim that `a & b ^ c` first evaluates `a & b` though. – M.M Jun 17 '21 at 05:25
  • @M.M I'm plenty familiar with programming lingo, thanks. This question is tagged [tag:c], and the usage that I quoted from *The C Programming Language* is absolutely commonplace. The standard is largely based on that book and (in part) codifies the precedence table from that book. Precedence does *not* refer to associativity; associativity tells us how to order two operations that have the same precedence. Contrary to your first comment, this answer perfectly explains the OP's question. – Caleb Jun 17 '21 at 05:36
  • @Caleb by "operator associativity" I mean the way that operands are associated with operators, e.g. that the expression is a `+`-expression and not a `*`-expression. Not referring to associativity within precedence levels as you are describing. Maybe "expression grouping" would have been a better terminology, or something. This answer is incorrect as `a` can be evaluated before `b |= c` ; and furthermore, `a` can be updated before `b` is updated. – M.M Jun 17 '21 at 05:43
  • @M.M `a` can be evaluated, yes, but `+=` **cannot** be applied (in this case) before `|=` because the two operators have the same precedence level and because they're right-associative. The OP is asking why `a+=b|=c` is equal to `a+=(b|=c)` rather than `(a+=b)|=c`. I agree that "grouping of expressions" would be a better term than "associativity," but in any case it's true that `b|=c` must be evaluated before the result can be added to `a` (which may indeed have been evaluated first, to the extent that a *evaluated* is meaningful for a variable). Cheers. – Caleb Jun 17 '21 at 06:12
  • @Caleb Still not correct. An allowed order of operations is : (pseudocode) `t = b|c; a = a + t; b = t;`. This difference may be observable if `a` and `b` are volatiles that control hardware when written. – M.M Jun 17 '21 at 07:17
  • The term "evaluated" is defined in the Standard; it has two aspects *value computation* and *side-effect*. For an lvalue, value computation means determining the memory location (not reading or writing), there can be a side-effect too. E.g. `*a() += (*b() |= c())` might still call `a()` before calling `b()` ; and the two writes can occur in either order. The value computation of the `|=` operator necessarily occurs before the side-effect of `+=` operator . – M.M Jun 17 '21 at 07:18
1

When the calculation formulas have the same priority.

It will be resolved from the right side.

In other words, the result is the same as the following formula.

b=b|c;
a=a+b;
hashito
  • 94
  • 6