Beginner in need of a simple explanation of the difference between order of evaluation and precedence/associativityWhy are these constructs using pre and post-increment undefined behavior?Why does a=(b++) have the same behavior as a=b++?Operator Precedence vs Order of EvaluationOperator Precedence vs Order of EvaluationPrecedence of && over ||Who defines C operator precedence and associativity?Associativity of function call operator in CWhat is the difference between a sequence point and operator precedence?Ternary operator in loop conditional: evaluation order / op. precedence unclearHow to justify C postfix increment operator with precedence table?*p++->str : Understanding evaluation of ->

What is a "soap"?

Graphs for which a calculus student can reasonably compute the arclength

How do some PhD students get 10+ papers? Is that what I need for landing good faculty position?

Are those flyers about apartment purchase a scam?

Swap on SSD in 2019?

Who invented Monoid?

If you know the location of an invisible creature, can you attack it?

Boss wants me to ignore a software API license prohibiting mass download

How to remove ambiguity: "... lives in the city of H, the capital of the province of NS, WHERE the unemployment rate is ..."?

How can God warn people of the upcoming rapture without disrupting society?

Are differences between uniformly distributed numbers uniformly distributed?

Tempoverlustspiel

If "more guns less crime", how do gun advocates explain that the EU has less crime than the US?

How should I write this passage to make it the most readable?

How big are the Choedan Kal?

Running code generated in realtime in JavaScript with eval()

What would it take to get a message to another star?

How would timezones work on a planet 100 times the size of our Earth

The cat exchanges places with a drawing of the cat

Can a bald person be a Nazir?

What can Amex do if I cancel their card after using the sign up bonus miles?

Why aren't rainbows blurred-out into nothing after they are produced?

Do Reform Jews believe in a theistic God?

What kind of liquid can be seen 'leaking' from the upper surface of the wing of a Boeing 737-800?



Beginner in need of a simple explanation of the difference between order of evaluation and precedence/associativity


Why are these constructs using pre and post-increment undefined behavior?Why does a=(b++) have the same behavior as a=b++?Operator Precedence vs Order of EvaluationOperator Precedence vs Order of EvaluationPrecedence of && over ||Who defines C operator precedence and associativity?Associativity of function call operator in CWhat is the difference between a sequence point and operator precedence?Ternary operator in loop conditional: evaluation order / op. precedence unclearHow to justify C postfix increment operator with precedence table?*p++->str : Understanding evaluation of ->






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








9















I am reading the end of the 2nd chapter of K&R and I'm having some difficulty understanding two specific unrelated example lines of code (which follow) along with commentary of them in the book:



x = f() + g();
a[i] = i++;


FIRST LINE - I have no trouble understanding that the standard does not specify the order of evaluation for the + operator, and that therefore it is unspecified whether f() or g() evaluates first (and that is why I think the question isn't a duplicate). My confusion stems from the fact that if we look up the C operator precedence chart it cites function calls as of highest precedence with left-to-right associativity. Now doesn't that mean that f() has to be called/evaluated before g()? Obviously not, but I don't know what I am missing.



SECOND LINE - Again the similar conundrum regarding whether the array is indexed to the initial value of i or the inceremented value. However, again the operator precedence chart cites array subscripting as of highest precedence with left-to-right associativity. Therefore wouldn't array subscripting be the first thing to be evaluated causing the array to be subscripted to the initial value of i and removing any unambiguity? Obviously not, and I'm missing something.



I do understand that compilers have the freedom to decide when side effects happen in an expression (between sequence points of course) and that that may cause undefined behaviour if the variable in question is used again in the same expression, however in the examples above it seems that any ambiguity is cleared by function calls and array subscripting having highest precedence and defined left-to-right associativity, so I fail to see the ambiguity.



I have a feeling that I have some fundamental misconception about the concepts of associativity, operator precedence and order of evaluation, but I can't point my finger on what it is, and similar questions/answers on this topic were out of my league to understand thoroughly at this point.



I don't think this question is a duplicate even though I'm not the first one to be confused by this on this forum, I believe that this question wasn't asked in this fashion before.










share|improve this question
























  • Related: Why are these constructs using pre and post-increment undefined behavior?

    – JL2210
    9 hours ago












  • As a general rule, if there's no requirement that something has to happen, then the behaviour is termed "undefined" and anything can and will happen instead. f() and g() will both be evaluated prior to the addition being performed. That much is assured, but as to the order, that doesn't matter and shouldn't impact your code. Same goes for arguments. When in doubt consult the C standard you're working with, whatever that is.

    – tadman
    9 hours ago











  • stackoverflow.com/questions/5473107/…

    – Mat
    9 hours ago

















9















I am reading the end of the 2nd chapter of K&R and I'm having some difficulty understanding two specific unrelated example lines of code (which follow) along with commentary of them in the book:



x = f() + g();
a[i] = i++;


FIRST LINE - I have no trouble understanding that the standard does not specify the order of evaluation for the + operator, and that therefore it is unspecified whether f() or g() evaluates first (and that is why I think the question isn't a duplicate). My confusion stems from the fact that if we look up the C operator precedence chart it cites function calls as of highest precedence with left-to-right associativity. Now doesn't that mean that f() has to be called/evaluated before g()? Obviously not, but I don't know what I am missing.



SECOND LINE - Again the similar conundrum regarding whether the array is indexed to the initial value of i or the inceremented value. However, again the operator precedence chart cites array subscripting as of highest precedence with left-to-right associativity. Therefore wouldn't array subscripting be the first thing to be evaluated causing the array to be subscripted to the initial value of i and removing any unambiguity? Obviously not, and I'm missing something.



I do understand that compilers have the freedom to decide when side effects happen in an expression (between sequence points of course) and that that may cause undefined behaviour if the variable in question is used again in the same expression, however in the examples above it seems that any ambiguity is cleared by function calls and array subscripting having highest precedence and defined left-to-right associativity, so I fail to see the ambiguity.



I have a feeling that I have some fundamental misconception about the concepts of associativity, operator precedence and order of evaluation, but I can't point my finger on what it is, and similar questions/answers on this topic were out of my league to understand thoroughly at this point.



I don't think this question is a duplicate even though I'm not the first one to be confused by this on this forum, I believe that this question wasn't asked in this fashion before.










share|improve this question
























  • Related: Why are these constructs using pre and post-increment undefined behavior?

    – JL2210
    9 hours ago












  • As a general rule, if there's no requirement that something has to happen, then the behaviour is termed "undefined" and anything can and will happen instead. f() and g() will both be evaluated prior to the addition being performed. That much is assured, but as to the order, that doesn't matter and shouldn't impact your code. Same goes for arguments. When in doubt consult the C standard you're working with, whatever that is.

    – tadman
    9 hours ago











  • stackoverflow.com/questions/5473107/…

    – Mat
    9 hours ago













9












9








9


1






I am reading the end of the 2nd chapter of K&R and I'm having some difficulty understanding two specific unrelated example lines of code (which follow) along with commentary of them in the book:



x = f() + g();
a[i] = i++;


FIRST LINE - I have no trouble understanding that the standard does not specify the order of evaluation for the + operator, and that therefore it is unspecified whether f() or g() evaluates first (and that is why I think the question isn't a duplicate). My confusion stems from the fact that if we look up the C operator precedence chart it cites function calls as of highest precedence with left-to-right associativity. Now doesn't that mean that f() has to be called/evaluated before g()? Obviously not, but I don't know what I am missing.



SECOND LINE - Again the similar conundrum regarding whether the array is indexed to the initial value of i or the inceremented value. However, again the operator precedence chart cites array subscripting as of highest precedence with left-to-right associativity. Therefore wouldn't array subscripting be the first thing to be evaluated causing the array to be subscripted to the initial value of i and removing any unambiguity? Obviously not, and I'm missing something.



I do understand that compilers have the freedom to decide when side effects happen in an expression (between sequence points of course) and that that may cause undefined behaviour if the variable in question is used again in the same expression, however in the examples above it seems that any ambiguity is cleared by function calls and array subscripting having highest precedence and defined left-to-right associativity, so I fail to see the ambiguity.



I have a feeling that I have some fundamental misconception about the concepts of associativity, operator precedence and order of evaluation, but I can't point my finger on what it is, and similar questions/answers on this topic were out of my league to understand thoroughly at this point.



I don't think this question is a duplicate even though I'm not the first one to be confused by this on this forum, I believe that this question wasn't asked in this fashion before.










share|improve this question














I am reading the end of the 2nd chapter of K&R and I'm having some difficulty understanding two specific unrelated example lines of code (which follow) along with commentary of them in the book:



x = f() + g();
a[i] = i++;


FIRST LINE - I have no trouble understanding that the standard does not specify the order of evaluation for the + operator, and that therefore it is unspecified whether f() or g() evaluates first (and that is why I think the question isn't a duplicate). My confusion stems from the fact that if we look up the C operator precedence chart it cites function calls as of highest precedence with left-to-right associativity. Now doesn't that mean that f() has to be called/evaluated before g()? Obviously not, but I don't know what I am missing.



SECOND LINE - Again the similar conundrum regarding whether the array is indexed to the initial value of i or the inceremented value. However, again the operator precedence chart cites array subscripting as of highest precedence with left-to-right associativity. Therefore wouldn't array subscripting be the first thing to be evaluated causing the array to be subscripted to the initial value of i and removing any unambiguity? Obviously not, and I'm missing something.



I do understand that compilers have the freedom to decide when side effects happen in an expression (between sequence points of course) and that that may cause undefined behaviour if the variable in question is used again in the same expression, however in the examples above it seems that any ambiguity is cleared by function calls and array subscripting having highest precedence and defined left-to-right associativity, so I fail to see the ambiguity.



I have a feeling that I have some fundamental misconception about the concepts of associativity, operator precedence and order of evaluation, but I can't point my finger on what it is, and similar questions/answers on this topic were out of my league to understand thoroughly at this point.



I don't think this question is a duplicate even though I'm not the first one to be confused by this on this forum, I believe that this question wasn't asked in this fashion before.







c






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 9 hours ago









ahraahra

1485 bronze badges




1485 bronze badges















  • Related: Why are these constructs using pre and post-increment undefined behavior?

    – JL2210
    9 hours ago












  • As a general rule, if there's no requirement that something has to happen, then the behaviour is termed "undefined" and anything can and will happen instead. f() and g() will both be evaluated prior to the addition being performed. That much is assured, but as to the order, that doesn't matter and shouldn't impact your code. Same goes for arguments. When in doubt consult the C standard you're working with, whatever that is.

    – tadman
    9 hours ago











  • stackoverflow.com/questions/5473107/…

    – Mat
    9 hours ago

















  • Related: Why are these constructs using pre and post-increment undefined behavior?

    – JL2210
    9 hours ago












  • As a general rule, if there's no requirement that something has to happen, then the behaviour is termed "undefined" and anything can and will happen instead. f() and g() will both be evaluated prior to the addition being performed. That much is assured, but as to the order, that doesn't matter and shouldn't impact your code. Same goes for arguments. When in doubt consult the C standard you're working with, whatever that is.

    – tadman
    9 hours ago











  • stackoverflow.com/questions/5473107/…

    – Mat
    9 hours ago
















Related: Why are these constructs using pre and post-increment undefined behavior?

– JL2210
9 hours ago






Related: Why are these constructs using pre and post-increment undefined behavior?

– JL2210
9 hours ago














As a general rule, if there's no requirement that something has to happen, then the behaviour is termed "undefined" and anything can and will happen instead. f() and g() will both be evaluated prior to the addition being performed. That much is assured, but as to the order, that doesn't matter and shouldn't impact your code. Same goes for arguments. When in doubt consult the C standard you're working with, whatever that is.

– tadman
9 hours ago





As a general rule, if there's no requirement that something has to happen, then the behaviour is termed "undefined" and anything can and will happen instead. f() and g() will both be evaluated prior to the addition being performed. That much is assured, but as to the order, that doesn't matter and shouldn't impact your code. Same goes for arguments. When in doubt consult the C standard you're working with, whatever that is.

– tadman
9 hours ago













stackoverflow.com/questions/5473107/…

– Mat
9 hours ago





stackoverflow.com/questions/5473107/…

– Mat
9 hours ago












5 Answers
5






active

oldest

votes


















5














FIRST LINE



The left-to-right associativity means that an expression such as f()()() is evaluated as ((f())())(). The associativity of the function call operator () says nothing about its relationship with other operators such as +.



(Note that with unary operators, associativity is rather pointless in general.)



SECOND LINE



Operator precedence affects parsing, not order of evaluation. The fact that [] has higher precedence than = means that the expression is parsed as (a[i]) = (i++). It says very little about evaluation order; a[i] and i++ must both be evaluated before the assignment, but nothing is said about their order with respect to each other.



To hopefully clear up confusion:



Associativity controls parsing and tells you whether a + b + c is parsed as (a + b) + c (left-to-right) or as a + (b + c) (right-to-left).



Precedence also controls parsing and tells you whether a + b * c is parsed as (a + b) * c (+ has higher precedence than *) or as a + (b * c) (* has higher precedence than +).



Order of evaluation controls which values need to be evaluated in which order. Parts of it can follow from associativity or precedence (an operand must be evaluated before it's used), but it's seldom fully defined by them.






share|improve this answer




















  • 1





    Associativity is not relevant to f()()(). There is no other way to structure the expression, so there is no choice for associativity to resolve. Associativity applies in a situation like a-b+c where there could (based on precedence alone) be a choice between (a-b)+c or a-(b+c). (And the C rules actually specify expression structure or parsing by grammar, not by explicit precedence or associativity direction.)

    – Eric Postpischil
    7 hours ago


















3














Precedence and associativity matter when an expression has more than one operator.



Associativity doesn't matter with addition, because as you may remember from grade school math, addition is commutative and associative -- there's no difference between (a + b) + c, a + (b + c), or (b + c) + a.



But consider subtraction. If you write



100 - 50 - 5


it matters whether you treat this as



(100 - 50) - 5 = 45


or



100 - (50 - 5) = 55


Left associativity means that the first interpretation will be used.



Precedence comes into play when you have different operators, e.g.



10 * 20 + 5


Since * has higher precedence than +, this is treated like



(10 * 20) + 5 = 205


rather than



10 * (20 + 5) = 250



Finally, order of evaluation is only noticeable when there are side effects or other dependencies between the sub-expressions. If you write



x = f() - g() - h()


and these functions each print something, the language doesn't specify the order in which the output will occur. Associativity doesn't change this. Even though the results will be subtracted in left-to-right order, it could call them in a different order, save the results somewhere, and then subtract them in the correct order. E.g. it could act as if you'd written:



temp_h = h();
temp_f = f();
temp_g = g();
x = (temp_f - temp_g) - temp_h;


Any reordering of the first 3 lines would be allowed as an interpretation.



Note that in some cases, computer arithmetic is not exactly like real arithmetic. Numbers in computers generally have limited range or precision, so there can be anomalous results (e.g. overflow if the result of addition is too large). This could cause different results depending on the order of operations even with operators that are theoretically associative, e.g. mathematically the following two expressions are equivalent:



x + y - z = (x + y) - z
y - z + x = (y - z) + x


But if x + y overflows, the results can be different. Use explicit parentheses to override the default associativity if necessary to avoid a problem like this.






share|improve this answer


































    2














    Regarding your first question:



    x = f() + g();


    The left-to-right associativity relates to operators at the same level that are directly grouped together. For example:



    x = a + b - c;


    Here the + and - operators have the same precedence level, so a + b is first evaluated, then a + b - c.



    For an example more related to yours, imagine a function that returns a function pointer. You could then do something like this:



    x()();


    In this case, the function x must be called first, then the function pointer returned by x is called.



    For the second:



    a[i] = i++;


    The side effect of the postincrement operator is not guaranteed to occur until the next sequence point. Because there are no sequence points in this expression, the i on the left side may be evaluated before or after the side effect of ++. This invokes undefined behavior due to both reading and writing a variable without a sequence point.






    share|improve this answer
































      2














      1. It's not really meaningful to say that function calls have left-to-right associativity, and even if it were meaningful, this would apply to single calls like f(), or nested calls like f(g()). It wouldn't say anything about two separate function calls on either side of a + operator.

      2. Precedence and associativity don't help us at all in the expression a[i] = i++. There simply is no rule that says precisely when i++ stores the new result back into i, meaning that there is no rule to tell us whether the a[i] part uses the old or the new value. That's why this expression is undefined.

      Precedence tells you what happens when you have two different operators that might apply. In a + b * c, does the + or the * apply first? In *p++, does the * or the ++ apply first? Precedence answers these questions.



      Associativity tells you what happens when you have a string of the same operators in a row. In a + b + c, which + applies first?



      But the answers to these questions (that is, the answers supplied by the precedence and associativity rules) apply rather narrowly. They tell you which of the two operators you were wondering about apply first, but they do not tell you much of anything about the bigger expression, or about the smaller subexpressions "underneath" the operators you were wondering about. (For example, if I wrote (a - b) + (c - d) * (e - f), there's no rule to say which of the subtractions happens first.)



      The bottom line is that precedence and associativity do not fully determine order of evaluation. Let's say that again in a slightly different way: precedence and associativity partially determine the order of evaluation in certain expressions, but they do not fully determine the order of evaluation in all expressions.



      In C, some aspects of the order of evaluation are unspecified, and some are undefined. (This is by contrast to, as I understand it, Java, where all aspects of evaluation order are defined.)



      In a + b * c precedence tells us that the multiplication happens before the addition, and in a + b + c, associativity tells us that the left-hand addition happens before the right-hand one. But in f() + g() + x() * y() there's nothing to tell us which order the function calls happen in, even though (once they've been called) precedence and associativity tell us in what order their return values will be multiplied and added together.



      See also this answer which, although it's about a different question, explains the same points in more detail.






      share|improve this answer


































        1














        FIRST LINE - Associativity is not relevant here. Associativity only really comes into play when you have a sequence of operators with the same precedence. Let's take the expression x + y - z. The additive operators + and - are left-associative, so that sequence is parsed as (x + y) - z - IOW, the result of z is subtracted from the result of x + y.



        THIS DOES NOT MEAN that any of x, y, or z have to be evaluated in any particular order. It does not mean that x + y must be evaluated before z. It only means that the result of x + y must be known before the result of z is subtracted from it.



        Regarding x = f() + g(), all that matters is that the results of f() and g() are known before they can be added together - it does not mean that f() must be evaluated before g(). And again, associativity has no effect here.



        SECOND LINE - This statement invokes undefined behavior precisely because the order of operations is unspecified (strictly speaking, the expressions a[i] and i++ are unsequenced with respect to each other). You cannot both update an object (i++) and use its value in a computation (a[i]) in the same expression without an intervening sequence point. The result will not be consistent or predictable from build to build (it doesn't even have to be consistent from run to run of the same build). Expressions like a[i] = i++ (or a[i++] = i) and x = x++ all have undefined behavior, and the result can be quite literally anything.



        Note that the &&, ||, ?:, and comma operators do force left-to-right evaluation and introduce sequence points, so an expression like



        i++ && a[i]


        is well-defined - i++ will be evaluated first and its side effect will be applied before a[i] is evaluated.



        Precedence and associativity fall out of the language grammar - for example, the grammar for the additive operators + and - is



        additive-expression:
        multiplicative-expression
        additive-expression + multiplicative-expression
        additive-expression - multiplicative-expression


        IOW, an additive-expression can produce a single multiplicative-expression, or it can produce another additive-expression followed by an additive operator followed by a multiplicative-expression. Let's see how this plays out with x + y - z:



        x -- additive-expression ---------+
        |
        + +-- additive-expression --+
        | |
        y -- multiplicative-expression ---+ |
        +-- additive-expression
        - |
        |
        z -- multiplicative-expression -----------------------------+


        You can see that x + y is grouped together into an additive-expression first, and then that expression is grouped with z to form another additive-expression.






        share|improve this answer



























          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f57484829%2fbeginner-in-need-of-a-simple-explanation-of-the-difference-between-order-of-eval%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          5 Answers
          5






          active

          oldest

          votes








          5 Answers
          5






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          5














          FIRST LINE



          The left-to-right associativity means that an expression such as f()()() is evaluated as ((f())())(). The associativity of the function call operator () says nothing about its relationship with other operators such as +.



          (Note that with unary operators, associativity is rather pointless in general.)



          SECOND LINE



          Operator precedence affects parsing, not order of evaluation. The fact that [] has higher precedence than = means that the expression is parsed as (a[i]) = (i++). It says very little about evaluation order; a[i] and i++ must both be evaluated before the assignment, but nothing is said about their order with respect to each other.



          To hopefully clear up confusion:



          Associativity controls parsing and tells you whether a + b + c is parsed as (a + b) + c (left-to-right) or as a + (b + c) (right-to-left).



          Precedence also controls parsing and tells you whether a + b * c is parsed as (a + b) * c (+ has higher precedence than *) or as a + (b * c) (* has higher precedence than +).



          Order of evaluation controls which values need to be evaluated in which order. Parts of it can follow from associativity or precedence (an operand must be evaluated before it's used), but it's seldom fully defined by them.






          share|improve this answer




















          • 1





            Associativity is not relevant to f()()(). There is no other way to structure the expression, so there is no choice for associativity to resolve. Associativity applies in a situation like a-b+c where there could (based on precedence alone) be a choice between (a-b)+c or a-(b+c). (And the C rules actually specify expression structure or parsing by grammar, not by explicit precedence or associativity direction.)

            – Eric Postpischil
            7 hours ago















          5














          FIRST LINE



          The left-to-right associativity means that an expression such as f()()() is evaluated as ((f())())(). The associativity of the function call operator () says nothing about its relationship with other operators such as +.



          (Note that with unary operators, associativity is rather pointless in general.)



          SECOND LINE



          Operator precedence affects parsing, not order of evaluation. The fact that [] has higher precedence than = means that the expression is parsed as (a[i]) = (i++). It says very little about evaluation order; a[i] and i++ must both be evaluated before the assignment, but nothing is said about their order with respect to each other.



          To hopefully clear up confusion:



          Associativity controls parsing and tells you whether a + b + c is parsed as (a + b) + c (left-to-right) or as a + (b + c) (right-to-left).



          Precedence also controls parsing and tells you whether a + b * c is parsed as (a + b) * c (+ has higher precedence than *) or as a + (b * c) (* has higher precedence than +).



          Order of evaluation controls which values need to be evaluated in which order. Parts of it can follow from associativity or precedence (an operand must be evaluated before it's used), but it's seldom fully defined by them.






          share|improve this answer




















          • 1





            Associativity is not relevant to f()()(). There is no other way to structure the expression, so there is no choice for associativity to resolve. Associativity applies in a situation like a-b+c where there could (based on precedence alone) be a choice between (a-b)+c or a-(b+c). (And the C rules actually specify expression structure or parsing by grammar, not by explicit precedence or associativity direction.)

            – Eric Postpischil
            7 hours ago













          5












          5








          5







          FIRST LINE



          The left-to-right associativity means that an expression such as f()()() is evaluated as ((f())())(). The associativity of the function call operator () says nothing about its relationship with other operators such as +.



          (Note that with unary operators, associativity is rather pointless in general.)



          SECOND LINE



          Operator precedence affects parsing, not order of evaluation. The fact that [] has higher precedence than = means that the expression is parsed as (a[i]) = (i++). It says very little about evaluation order; a[i] and i++ must both be evaluated before the assignment, but nothing is said about their order with respect to each other.



          To hopefully clear up confusion:



          Associativity controls parsing and tells you whether a + b + c is parsed as (a + b) + c (left-to-right) or as a + (b + c) (right-to-left).



          Precedence also controls parsing and tells you whether a + b * c is parsed as (a + b) * c (+ has higher precedence than *) or as a + (b * c) (* has higher precedence than +).



          Order of evaluation controls which values need to be evaluated in which order. Parts of it can follow from associativity or precedence (an operand must be evaluated before it's used), but it's seldom fully defined by them.






          share|improve this answer













          FIRST LINE



          The left-to-right associativity means that an expression such as f()()() is evaluated as ((f())())(). The associativity of the function call operator () says nothing about its relationship with other operators such as +.



          (Note that with unary operators, associativity is rather pointless in general.)



          SECOND LINE



          Operator precedence affects parsing, not order of evaluation. The fact that [] has higher precedence than = means that the expression is parsed as (a[i]) = (i++). It says very little about evaluation order; a[i] and i++ must both be evaluated before the assignment, but nothing is said about their order with respect to each other.



          To hopefully clear up confusion:



          Associativity controls parsing and tells you whether a + b + c is parsed as (a + b) + c (left-to-right) or as a + (b + c) (right-to-left).



          Precedence also controls parsing and tells you whether a + b * c is parsed as (a + b) * c (+ has higher precedence than *) or as a + (b * c) (* has higher precedence than +).



          Order of evaluation controls which values need to be evaluated in which order. Parts of it can follow from associativity or precedence (an operand must be evaluated before it's used), but it's seldom fully defined by them.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 9 hours ago









          AngewAngew

          141k13 gold badges282 silver badges370 bronze badges




          141k13 gold badges282 silver badges370 bronze badges










          • 1





            Associativity is not relevant to f()()(). There is no other way to structure the expression, so there is no choice for associativity to resolve. Associativity applies in a situation like a-b+c where there could (based on precedence alone) be a choice between (a-b)+c or a-(b+c). (And the C rules actually specify expression structure or parsing by grammar, not by explicit precedence or associativity direction.)

            – Eric Postpischil
            7 hours ago












          • 1





            Associativity is not relevant to f()()(). There is no other way to structure the expression, so there is no choice for associativity to resolve. Associativity applies in a situation like a-b+c where there could (based on precedence alone) be a choice between (a-b)+c or a-(b+c). (And the C rules actually specify expression structure or parsing by grammar, not by explicit precedence or associativity direction.)

            – Eric Postpischil
            7 hours ago







          1




          1





          Associativity is not relevant to f()()(). There is no other way to structure the expression, so there is no choice for associativity to resolve. Associativity applies in a situation like a-b+c where there could (based on precedence alone) be a choice between (a-b)+c or a-(b+c). (And the C rules actually specify expression structure or parsing by grammar, not by explicit precedence or associativity direction.)

          – Eric Postpischil
          7 hours ago





          Associativity is not relevant to f()()(). There is no other way to structure the expression, so there is no choice for associativity to resolve. Associativity applies in a situation like a-b+c where there could (based on precedence alone) be a choice between (a-b)+c or a-(b+c). (And the C rules actually specify expression structure or parsing by grammar, not by explicit precedence or associativity direction.)

          – Eric Postpischil
          7 hours ago













          3














          Precedence and associativity matter when an expression has more than one operator.



          Associativity doesn't matter with addition, because as you may remember from grade school math, addition is commutative and associative -- there's no difference between (a + b) + c, a + (b + c), or (b + c) + a.



          But consider subtraction. If you write



          100 - 50 - 5


          it matters whether you treat this as



          (100 - 50) - 5 = 45


          or



          100 - (50 - 5) = 55


          Left associativity means that the first interpretation will be used.



          Precedence comes into play when you have different operators, e.g.



          10 * 20 + 5


          Since * has higher precedence than +, this is treated like



          (10 * 20) + 5 = 205


          rather than



          10 * (20 + 5) = 250



          Finally, order of evaluation is only noticeable when there are side effects or other dependencies between the sub-expressions. If you write



          x = f() - g() - h()


          and these functions each print something, the language doesn't specify the order in which the output will occur. Associativity doesn't change this. Even though the results will be subtracted in left-to-right order, it could call them in a different order, save the results somewhere, and then subtract them in the correct order. E.g. it could act as if you'd written:



          temp_h = h();
          temp_f = f();
          temp_g = g();
          x = (temp_f - temp_g) - temp_h;


          Any reordering of the first 3 lines would be allowed as an interpretation.



          Note that in some cases, computer arithmetic is not exactly like real arithmetic. Numbers in computers generally have limited range or precision, so there can be anomalous results (e.g. overflow if the result of addition is too large). This could cause different results depending on the order of operations even with operators that are theoretically associative, e.g. mathematically the following two expressions are equivalent:



          x + y - z = (x + y) - z
          y - z + x = (y - z) + x


          But if x + y overflows, the results can be different. Use explicit parentheses to override the default associativity if necessary to avoid a problem like this.






          share|improve this answer































            3














            Precedence and associativity matter when an expression has more than one operator.



            Associativity doesn't matter with addition, because as you may remember from grade school math, addition is commutative and associative -- there's no difference between (a + b) + c, a + (b + c), or (b + c) + a.



            But consider subtraction. If you write



            100 - 50 - 5


            it matters whether you treat this as



            (100 - 50) - 5 = 45


            or



            100 - (50 - 5) = 55


            Left associativity means that the first interpretation will be used.



            Precedence comes into play when you have different operators, e.g.



            10 * 20 + 5


            Since * has higher precedence than +, this is treated like



            (10 * 20) + 5 = 205


            rather than



            10 * (20 + 5) = 250



            Finally, order of evaluation is only noticeable when there are side effects or other dependencies between the sub-expressions. If you write



            x = f() - g() - h()


            and these functions each print something, the language doesn't specify the order in which the output will occur. Associativity doesn't change this. Even though the results will be subtracted in left-to-right order, it could call them in a different order, save the results somewhere, and then subtract them in the correct order. E.g. it could act as if you'd written:



            temp_h = h();
            temp_f = f();
            temp_g = g();
            x = (temp_f - temp_g) - temp_h;


            Any reordering of the first 3 lines would be allowed as an interpretation.



            Note that in some cases, computer arithmetic is not exactly like real arithmetic. Numbers in computers generally have limited range or precision, so there can be anomalous results (e.g. overflow if the result of addition is too large). This could cause different results depending on the order of operations even with operators that are theoretically associative, e.g. mathematically the following two expressions are equivalent:



            x + y - z = (x + y) - z
            y - z + x = (y - z) + x


            But if x + y overflows, the results can be different. Use explicit parentheses to override the default associativity if necessary to avoid a problem like this.






            share|improve this answer





























              3












              3








              3







              Precedence and associativity matter when an expression has more than one operator.



              Associativity doesn't matter with addition, because as you may remember from grade school math, addition is commutative and associative -- there's no difference between (a + b) + c, a + (b + c), or (b + c) + a.



              But consider subtraction. If you write



              100 - 50 - 5


              it matters whether you treat this as



              (100 - 50) - 5 = 45


              or



              100 - (50 - 5) = 55


              Left associativity means that the first interpretation will be used.



              Precedence comes into play when you have different operators, e.g.



              10 * 20 + 5


              Since * has higher precedence than +, this is treated like



              (10 * 20) + 5 = 205


              rather than



              10 * (20 + 5) = 250



              Finally, order of evaluation is only noticeable when there are side effects or other dependencies between the sub-expressions. If you write



              x = f() - g() - h()


              and these functions each print something, the language doesn't specify the order in which the output will occur. Associativity doesn't change this. Even though the results will be subtracted in left-to-right order, it could call them in a different order, save the results somewhere, and then subtract them in the correct order. E.g. it could act as if you'd written:



              temp_h = h();
              temp_f = f();
              temp_g = g();
              x = (temp_f - temp_g) - temp_h;


              Any reordering of the first 3 lines would be allowed as an interpretation.



              Note that in some cases, computer arithmetic is not exactly like real arithmetic. Numbers in computers generally have limited range or precision, so there can be anomalous results (e.g. overflow if the result of addition is too large). This could cause different results depending on the order of operations even with operators that are theoretically associative, e.g. mathematically the following two expressions are equivalent:



              x + y - z = (x + y) - z
              y - z + x = (y - z) + x


              But if x + y overflows, the results can be different. Use explicit parentheses to override the default associativity if necessary to avoid a problem like this.






              share|improve this answer















              Precedence and associativity matter when an expression has more than one operator.



              Associativity doesn't matter with addition, because as you may remember from grade school math, addition is commutative and associative -- there's no difference between (a + b) + c, a + (b + c), or (b + c) + a.



              But consider subtraction. If you write



              100 - 50 - 5


              it matters whether you treat this as



              (100 - 50) - 5 = 45


              or



              100 - (50 - 5) = 55


              Left associativity means that the first interpretation will be used.



              Precedence comes into play when you have different operators, e.g.



              10 * 20 + 5


              Since * has higher precedence than +, this is treated like



              (10 * 20) + 5 = 205


              rather than



              10 * (20 + 5) = 250



              Finally, order of evaluation is only noticeable when there are side effects or other dependencies between the sub-expressions. If you write



              x = f() - g() - h()


              and these functions each print something, the language doesn't specify the order in which the output will occur. Associativity doesn't change this. Even though the results will be subtracted in left-to-right order, it could call them in a different order, save the results somewhere, and then subtract them in the correct order. E.g. it could act as if you'd written:



              temp_h = h();
              temp_f = f();
              temp_g = g();
              x = (temp_f - temp_g) - temp_h;


              Any reordering of the first 3 lines would be allowed as an interpretation.



              Note that in some cases, computer arithmetic is not exactly like real arithmetic. Numbers in computers generally have limited range or precision, so there can be anomalous results (e.g. overflow if the result of addition is too large). This could cause different results depending on the order of operations even with operators that are theoretically associative, e.g. mathematically the following two expressions are equivalent:



              x + y - z = (x + y) - z
              y - z + x = (y - z) + x


              But if x + y overflows, the results can be different. Use explicit parentheses to override the default associativity if necessary to avoid a problem like this.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited 8 hours ago

























              answered 9 hours ago









              BarmarBarmar

              460k38 gold badges282 silver badges387 bronze badges




              460k38 gold badges282 silver badges387 bronze badges
























                  2














                  Regarding your first question:



                  x = f() + g();


                  The left-to-right associativity relates to operators at the same level that are directly grouped together. For example:



                  x = a + b - c;


                  Here the + and - operators have the same precedence level, so a + b is first evaluated, then a + b - c.



                  For an example more related to yours, imagine a function that returns a function pointer. You could then do something like this:



                  x()();


                  In this case, the function x must be called first, then the function pointer returned by x is called.



                  For the second:



                  a[i] = i++;


                  The side effect of the postincrement operator is not guaranteed to occur until the next sequence point. Because there are no sequence points in this expression, the i on the left side may be evaluated before or after the side effect of ++. This invokes undefined behavior due to both reading and writing a variable without a sequence point.






                  share|improve this answer





























                    2














                    Regarding your first question:



                    x = f() + g();


                    The left-to-right associativity relates to operators at the same level that are directly grouped together. For example:



                    x = a + b - c;


                    Here the + and - operators have the same precedence level, so a + b is first evaluated, then a + b - c.



                    For an example more related to yours, imagine a function that returns a function pointer. You could then do something like this:



                    x()();


                    In this case, the function x must be called first, then the function pointer returned by x is called.



                    For the second:



                    a[i] = i++;


                    The side effect of the postincrement operator is not guaranteed to occur until the next sequence point. Because there are no sequence points in this expression, the i on the left side may be evaluated before or after the side effect of ++. This invokes undefined behavior due to both reading and writing a variable without a sequence point.






                    share|improve this answer



























                      2












                      2








                      2







                      Regarding your first question:



                      x = f() + g();


                      The left-to-right associativity relates to operators at the same level that are directly grouped together. For example:



                      x = a + b - c;


                      Here the + and - operators have the same precedence level, so a + b is first evaluated, then a + b - c.



                      For an example more related to yours, imagine a function that returns a function pointer. You could then do something like this:



                      x()();


                      In this case, the function x must be called first, then the function pointer returned by x is called.



                      For the second:



                      a[i] = i++;


                      The side effect of the postincrement operator is not guaranteed to occur until the next sequence point. Because there are no sequence points in this expression, the i on the left side may be evaluated before or after the side effect of ++. This invokes undefined behavior due to both reading and writing a variable without a sequence point.






                      share|improve this answer













                      Regarding your first question:



                      x = f() + g();


                      The left-to-right associativity relates to operators at the same level that are directly grouped together. For example:



                      x = a + b - c;


                      Here the + and - operators have the same precedence level, so a + b is first evaluated, then a + b - c.



                      For an example more related to yours, imagine a function that returns a function pointer. You could then do something like this:



                      x()();


                      In this case, the function x must be called first, then the function pointer returned by x is called.



                      For the second:



                      a[i] = i++;


                      The side effect of the postincrement operator is not guaranteed to occur until the next sequence point. Because there are no sequence points in this expression, the i on the left side may be evaluated before or after the side effect of ++. This invokes undefined behavior due to both reading and writing a variable without a sequence point.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered 9 hours ago









                      dbushdbush

                      111k15 gold badges124 silver badges157 bronze badges




                      111k15 gold badges124 silver badges157 bronze badges
























                          2














                          1. It's not really meaningful to say that function calls have left-to-right associativity, and even if it were meaningful, this would apply to single calls like f(), or nested calls like f(g()). It wouldn't say anything about two separate function calls on either side of a + operator.

                          2. Precedence and associativity don't help us at all in the expression a[i] = i++. There simply is no rule that says precisely when i++ stores the new result back into i, meaning that there is no rule to tell us whether the a[i] part uses the old or the new value. That's why this expression is undefined.

                          Precedence tells you what happens when you have two different operators that might apply. In a + b * c, does the + or the * apply first? In *p++, does the * or the ++ apply first? Precedence answers these questions.



                          Associativity tells you what happens when you have a string of the same operators in a row. In a + b + c, which + applies first?



                          But the answers to these questions (that is, the answers supplied by the precedence and associativity rules) apply rather narrowly. They tell you which of the two operators you were wondering about apply first, but they do not tell you much of anything about the bigger expression, or about the smaller subexpressions "underneath" the operators you were wondering about. (For example, if I wrote (a - b) + (c - d) * (e - f), there's no rule to say which of the subtractions happens first.)



                          The bottom line is that precedence and associativity do not fully determine order of evaluation. Let's say that again in a slightly different way: precedence and associativity partially determine the order of evaluation in certain expressions, but they do not fully determine the order of evaluation in all expressions.



                          In C, some aspects of the order of evaluation are unspecified, and some are undefined. (This is by contrast to, as I understand it, Java, where all aspects of evaluation order are defined.)



                          In a + b * c precedence tells us that the multiplication happens before the addition, and in a + b + c, associativity tells us that the left-hand addition happens before the right-hand one. But in f() + g() + x() * y() there's nothing to tell us which order the function calls happen in, even though (once they've been called) precedence and associativity tell us in what order their return values will be multiplied and added together.



                          See also this answer which, although it's about a different question, explains the same points in more detail.






                          share|improve this answer































                            2














                            1. It's not really meaningful to say that function calls have left-to-right associativity, and even if it were meaningful, this would apply to single calls like f(), or nested calls like f(g()). It wouldn't say anything about two separate function calls on either side of a + operator.

                            2. Precedence and associativity don't help us at all in the expression a[i] = i++. There simply is no rule that says precisely when i++ stores the new result back into i, meaning that there is no rule to tell us whether the a[i] part uses the old or the new value. That's why this expression is undefined.

                            Precedence tells you what happens when you have two different operators that might apply. In a + b * c, does the + or the * apply first? In *p++, does the * or the ++ apply first? Precedence answers these questions.



                            Associativity tells you what happens when you have a string of the same operators in a row. In a + b + c, which + applies first?



                            But the answers to these questions (that is, the answers supplied by the precedence and associativity rules) apply rather narrowly. They tell you which of the two operators you were wondering about apply first, but they do not tell you much of anything about the bigger expression, or about the smaller subexpressions "underneath" the operators you were wondering about. (For example, if I wrote (a - b) + (c - d) * (e - f), there's no rule to say which of the subtractions happens first.)



                            The bottom line is that precedence and associativity do not fully determine order of evaluation. Let's say that again in a slightly different way: precedence and associativity partially determine the order of evaluation in certain expressions, but they do not fully determine the order of evaluation in all expressions.



                            In C, some aspects of the order of evaluation are unspecified, and some are undefined. (This is by contrast to, as I understand it, Java, where all aspects of evaluation order are defined.)



                            In a + b * c precedence tells us that the multiplication happens before the addition, and in a + b + c, associativity tells us that the left-hand addition happens before the right-hand one. But in f() + g() + x() * y() there's nothing to tell us which order the function calls happen in, even though (once they've been called) precedence and associativity tell us in what order their return values will be multiplied and added together.



                            See also this answer which, although it's about a different question, explains the same points in more detail.






                            share|improve this answer





























                              2












                              2








                              2







                              1. It's not really meaningful to say that function calls have left-to-right associativity, and even if it were meaningful, this would apply to single calls like f(), or nested calls like f(g()). It wouldn't say anything about two separate function calls on either side of a + operator.

                              2. Precedence and associativity don't help us at all in the expression a[i] = i++. There simply is no rule that says precisely when i++ stores the new result back into i, meaning that there is no rule to tell us whether the a[i] part uses the old or the new value. That's why this expression is undefined.

                              Precedence tells you what happens when you have two different operators that might apply. In a + b * c, does the + or the * apply first? In *p++, does the * or the ++ apply first? Precedence answers these questions.



                              Associativity tells you what happens when you have a string of the same operators in a row. In a + b + c, which + applies first?



                              But the answers to these questions (that is, the answers supplied by the precedence and associativity rules) apply rather narrowly. They tell you which of the two operators you were wondering about apply first, but they do not tell you much of anything about the bigger expression, or about the smaller subexpressions "underneath" the operators you were wondering about. (For example, if I wrote (a - b) + (c - d) * (e - f), there's no rule to say which of the subtractions happens first.)



                              The bottom line is that precedence and associativity do not fully determine order of evaluation. Let's say that again in a slightly different way: precedence and associativity partially determine the order of evaluation in certain expressions, but they do not fully determine the order of evaluation in all expressions.



                              In C, some aspects of the order of evaluation are unspecified, and some are undefined. (This is by contrast to, as I understand it, Java, where all aspects of evaluation order are defined.)



                              In a + b * c precedence tells us that the multiplication happens before the addition, and in a + b + c, associativity tells us that the left-hand addition happens before the right-hand one. But in f() + g() + x() * y() there's nothing to tell us which order the function calls happen in, even though (once they've been called) precedence and associativity tell us in what order their return values will be multiplied and added together.



                              See also this answer which, although it's about a different question, explains the same points in more detail.






                              share|improve this answer















                              1. It's not really meaningful to say that function calls have left-to-right associativity, and even if it were meaningful, this would apply to single calls like f(), or nested calls like f(g()). It wouldn't say anything about two separate function calls on either side of a + operator.

                              2. Precedence and associativity don't help us at all in the expression a[i] = i++. There simply is no rule that says precisely when i++ stores the new result back into i, meaning that there is no rule to tell us whether the a[i] part uses the old or the new value. That's why this expression is undefined.

                              Precedence tells you what happens when you have two different operators that might apply. In a + b * c, does the + or the * apply first? In *p++, does the * or the ++ apply first? Precedence answers these questions.



                              Associativity tells you what happens when you have a string of the same operators in a row. In a + b + c, which + applies first?



                              But the answers to these questions (that is, the answers supplied by the precedence and associativity rules) apply rather narrowly. They tell you which of the two operators you were wondering about apply first, but they do not tell you much of anything about the bigger expression, or about the smaller subexpressions "underneath" the operators you were wondering about. (For example, if I wrote (a - b) + (c - d) * (e - f), there's no rule to say which of the subtractions happens first.)



                              The bottom line is that precedence and associativity do not fully determine order of evaluation. Let's say that again in a slightly different way: precedence and associativity partially determine the order of evaluation in certain expressions, but they do not fully determine the order of evaluation in all expressions.



                              In C, some aspects of the order of evaluation are unspecified, and some are undefined. (This is by contrast to, as I understand it, Java, where all aspects of evaluation order are defined.)



                              In a + b * c precedence tells us that the multiplication happens before the addition, and in a + b + c, associativity tells us that the left-hand addition happens before the right-hand one. But in f() + g() + x() * y() there's nothing to tell us which order the function calls happen in, even though (once they've been called) precedence and associativity tell us in what order their return values will be multiplied and added together.



                              See also this answer which, although it's about a different question, explains the same points in more detail.







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited 8 hours ago

























                              answered 9 hours ago









                              Steve SummitSteve Summit

                              19.7k2 gold badges28 silver badges51 bronze badges




                              19.7k2 gold badges28 silver badges51 bronze badges
























                                  1














                                  FIRST LINE - Associativity is not relevant here. Associativity only really comes into play when you have a sequence of operators with the same precedence. Let's take the expression x + y - z. The additive operators + and - are left-associative, so that sequence is parsed as (x + y) - z - IOW, the result of z is subtracted from the result of x + y.



                                  THIS DOES NOT MEAN that any of x, y, or z have to be evaluated in any particular order. It does not mean that x + y must be evaluated before z. It only means that the result of x + y must be known before the result of z is subtracted from it.



                                  Regarding x = f() + g(), all that matters is that the results of f() and g() are known before they can be added together - it does not mean that f() must be evaluated before g(). And again, associativity has no effect here.



                                  SECOND LINE - This statement invokes undefined behavior precisely because the order of operations is unspecified (strictly speaking, the expressions a[i] and i++ are unsequenced with respect to each other). You cannot both update an object (i++) and use its value in a computation (a[i]) in the same expression without an intervening sequence point. The result will not be consistent or predictable from build to build (it doesn't even have to be consistent from run to run of the same build). Expressions like a[i] = i++ (or a[i++] = i) and x = x++ all have undefined behavior, and the result can be quite literally anything.



                                  Note that the &&, ||, ?:, and comma operators do force left-to-right evaluation and introduce sequence points, so an expression like



                                  i++ && a[i]


                                  is well-defined - i++ will be evaluated first and its side effect will be applied before a[i] is evaluated.



                                  Precedence and associativity fall out of the language grammar - for example, the grammar for the additive operators + and - is



                                  additive-expression:
                                  multiplicative-expression
                                  additive-expression + multiplicative-expression
                                  additive-expression - multiplicative-expression


                                  IOW, an additive-expression can produce a single multiplicative-expression, or it can produce another additive-expression followed by an additive operator followed by a multiplicative-expression. Let's see how this plays out with x + y - z:



                                  x -- additive-expression ---------+
                                  |
                                  + +-- additive-expression --+
                                  | |
                                  y -- multiplicative-expression ---+ |
                                  +-- additive-expression
                                  - |
                                  |
                                  z -- multiplicative-expression -----------------------------+


                                  You can see that x + y is grouped together into an additive-expression first, and then that expression is grouped with z to form another additive-expression.






                                  share|improve this answer





























                                    1














                                    FIRST LINE - Associativity is not relevant here. Associativity only really comes into play when you have a sequence of operators with the same precedence. Let's take the expression x + y - z. The additive operators + and - are left-associative, so that sequence is parsed as (x + y) - z - IOW, the result of z is subtracted from the result of x + y.



                                    THIS DOES NOT MEAN that any of x, y, or z have to be evaluated in any particular order. It does not mean that x + y must be evaluated before z. It only means that the result of x + y must be known before the result of z is subtracted from it.



                                    Regarding x = f() + g(), all that matters is that the results of f() and g() are known before they can be added together - it does not mean that f() must be evaluated before g(). And again, associativity has no effect here.



                                    SECOND LINE - This statement invokes undefined behavior precisely because the order of operations is unspecified (strictly speaking, the expressions a[i] and i++ are unsequenced with respect to each other). You cannot both update an object (i++) and use its value in a computation (a[i]) in the same expression without an intervening sequence point. The result will not be consistent or predictable from build to build (it doesn't even have to be consistent from run to run of the same build). Expressions like a[i] = i++ (or a[i++] = i) and x = x++ all have undefined behavior, and the result can be quite literally anything.



                                    Note that the &&, ||, ?:, and comma operators do force left-to-right evaluation and introduce sequence points, so an expression like



                                    i++ && a[i]


                                    is well-defined - i++ will be evaluated first and its side effect will be applied before a[i] is evaluated.



                                    Precedence and associativity fall out of the language grammar - for example, the grammar for the additive operators + and - is



                                    additive-expression:
                                    multiplicative-expression
                                    additive-expression + multiplicative-expression
                                    additive-expression - multiplicative-expression


                                    IOW, an additive-expression can produce a single multiplicative-expression, or it can produce another additive-expression followed by an additive operator followed by a multiplicative-expression. Let's see how this plays out with x + y - z:



                                    x -- additive-expression ---------+
                                    |
                                    + +-- additive-expression --+
                                    | |
                                    y -- multiplicative-expression ---+ |
                                    +-- additive-expression
                                    - |
                                    |
                                    z -- multiplicative-expression -----------------------------+


                                    You can see that x + y is grouped together into an additive-expression first, and then that expression is grouped with z to form another additive-expression.






                                    share|improve this answer



























                                      1












                                      1








                                      1







                                      FIRST LINE - Associativity is not relevant here. Associativity only really comes into play when you have a sequence of operators with the same precedence. Let's take the expression x + y - z. The additive operators + and - are left-associative, so that sequence is parsed as (x + y) - z - IOW, the result of z is subtracted from the result of x + y.



                                      THIS DOES NOT MEAN that any of x, y, or z have to be evaluated in any particular order. It does not mean that x + y must be evaluated before z. It only means that the result of x + y must be known before the result of z is subtracted from it.



                                      Regarding x = f() + g(), all that matters is that the results of f() and g() are known before they can be added together - it does not mean that f() must be evaluated before g(). And again, associativity has no effect here.



                                      SECOND LINE - This statement invokes undefined behavior precisely because the order of operations is unspecified (strictly speaking, the expressions a[i] and i++ are unsequenced with respect to each other). You cannot both update an object (i++) and use its value in a computation (a[i]) in the same expression without an intervening sequence point. The result will not be consistent or predictable from build to build (it doesn't even have to be consistent from run to run of the same build). Expressions like a[i] = i++ (or a[i++] = i) and x = x++ all have undefined behavior, and the result can be quite literally anything.



                                      Note that the &&, ||, ?:, and comma operators do force left-to-right evaluation and introduce sequence points, so an expression like



                                      i++ && a[i]


                                      is well-defined - i++ will be evaluated first and its side effect will be applied before a[i] is evaluated.



                                      Precedence and associativity fall out of the language grammar - for example, the grammar for the additive operators + and - is



                                      additive-expression:
                                      multiplicative-expression
                                      additive-expression + multiplicative-expression
                                      additive-expression - multiplicative-expression


                                      IOW, an additive-expression can produce a single multiplicative-expression, or it can produce another additive-expression followed by an additive operator followed by a multiplicative-expression. Let's see how this plays out with x + y - z:



                                      x -- additive-expression ---------+
                                      |
                                      + +-- additive-expression --+
                                      | |
                                      y -- multiplicative-expression ---+ |
                                      +-- additive-expression
                                      - |
                                      |
                                      z -- multiplicative-expression -----------------------------+


                                      You can see that x + y is grouped together into an additive-expression first, and then that expression is grouped with z to form another additive-expression.






                                      share|improve this answer













                                      FIRST LINE - Associativity is not relevant here. Associativity only really comes into play when you have a sequence of operators with the same precedence. Let's take the expression x + y - z. The additive operators + and - are left-associative, so that sequence is parsed as (x + y) - z - IOW, the result of z is subtracted from the result of x + y.



                                      THIS DOES NOT MEAN that any of x, y, or z have to be evaluated in any particular order. It does not mean that x + y must be evaluated before z. It only means that the result of x + y must be known before the result of z is subtracted from it.



                                      Regarding x = f() + g(), all that matters is that the results of f() and g() are known before they can be added together - it does not mean that f() must be evaluated before g(). And again, associativity has no effect here.



                                      SECOND LINE - This statement invokes undefined behavior precisely because the order of operations is unspecified (strictly speaking, the expressions a[i] and i++ are unsequenced with respect to each other). You cannot both update an object (i++) and use its value in a computation (a[i]) in the same expression without an intervening sequence point. The result will not be consistent or predictable from build to build (it doesn't even have to be consistent from run to run of the same build). Expressions like a[i] = i++ (or a[i++] = i) and x = x++ all have undefined behavior, and the result can be quite literally anything.



                                      Note that the &&, ||, ?:, and comma operators do force left-to-right evaluation and introduce sequence points, so an expression like



                                      i++ && a[i]


                                      is well-defined - i++ will be evaluated first and its side effect will be applied before a[i] is evaluated.



                                      Precedence and associativity fall out of the language grammar - for example, the grammar for the additive operators + and - is



                                      additive-expression:
                                      multiplicative-expression
                                      additive-expression + multiplicative-expression
                                      additive-expression - multiplicative-expression


                                      IOW, an additive-expression can produce a single multiplicative-expression, or it can produce another additive-expression followed by an additive operator followed by a multiplicative-expression. Let's see how this plays out with x + y - z:



                                      x -- additive-expression ---------+
                                      |
                                      + +-- additive-expression --+
                                      | |
                                      y -- multiplicative-expression ---+ |
                                      +-- additive-expression
                                      - |
                                      |
                                      z -- multiplicative-expression -----------------------------+


                                      You can see that x + y is grouped together into an additive-expression first, and then that expression is grouped with z to form another additive-expression.







                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered 7 hours ago









                                      John BodeJohn Bode

                                      87.4k15 gold badges87 silver badges155 bronze badges




                                      87.4k15 gold badges87 silver badges155 bronze badges






























                                          draft saved

                                          draft discarded
















































                                          Thanks for contributing an answer to Stack Overflow!


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid


                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.

                                          To learn more, see our tips on writing great answers.




                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function ()
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f57484829%2fbeginner-in-need-of-a-simple-explanation-of-the-difference-between-order-of-eval%23new-answer', 'question_page');

                                          );

                                          Post as a guest















                                          Required, but never shown





















































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown

































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown







                                          Popular posts from this blog

                                          Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

                                          Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

                                          199年 目錄 大件事 到箇年出世嗰人 到箇年死嗰人 節慶、風俗習慣 導覽選單