pjh@mccc.UUCP (Peter J. Holsberg) (02/18/88)
I find that associativity is a *very* difficult thing for me to explain, undoubtedly because I don't understand it! Would someone come to my rescue? Here's an example (assume that everything's been declared correctly): x = 3 * i ++; Book says that ++ has a higher precedence than *, and that ++ associates from R->L. That makes me think that ++ should be applied first, but I know it isn't. But ???? Also, what does K&R say about these: --- a; - -- a; -- - a; and ---a; - --a; -- -a; Thanks. -- Peter Holsberg UUCP: {rutgers!}princeton!mccc!pjh Technology Division CompuServe: 70240,334 Mercer College GEnie: PJHOLSBERG Trenton, NJ 08690 Voice: 1-609-586-4800
scjones@sdrc.UUCP (Larry Jones) (02/21/88)
In article <226@mccc.UUCP>, pjh@mccc.UUCP (Peter J. Holsberg) writes: > > I find that associativity is a *very* difficult thing for me to explain, > undoubtedly because I don't understand it! Would someone come to my > rescue? Here's an example (assume that everything's been declared > correctly): > > x = 3 * i ++; > > Book says that ++ has a higher precedence than *, and that ++ > associates from R->L. That makes me think that ++ should be applied > first, but I know it isn't. But ???? But ++ IS applied first! The key point here is that the RESULT of postfix ++ is the value BEFORE incrementation, not that postfix ++ is somehow deferred until later. It seems that you are confusing precedence and associativity. Precedence is used to specify the priority of DIFFERENT operators -- since multiplication has higher precedence that addition the expression A * B + C is interpreted as (A * B) + C. Associativity is used to specify the priority of operators with the SAME PRECEDENCE -- since subtraction associates left to right the expression A - B - C is interpreted as (A - B) - C rather than A - (B - C). > Also, what does K&R say about these: > --- a; K&R says that tokens are always the longest string which could be a vaild token so this is interpreted as --(-a) which is invalid since -- can only be applied to an lvalue (which -a is not). This has nothing to do with precedence or associativity - the innermost operator MUST be evaluated first, since the outer operator has no operand until it is. > - -- a; Interpreted as -(--a). Again this has nothing to do with precedence or associativity. > -- - a; Same as your first example. ---- Larry Jones UUCP: uunet!sdrc!scjones SDRC MAIL: 2000 Eastman Dr., Milford, OH 45150 AT&T: (513) 576-2070 "When all else fails, read the directions."
pjh@mccc.UUCP (Peter J. Holsberg) (02/23/88)
In article <224@sdrc.UUCP> scjones@sdrc.UUCP (Larry Jones) writes: |In article <226@mccc.UUCP>, pjh@mccc.UUCP (Peter J. Holsberg) writes: |> |> I find that associativity is a *very* difficult thing for me to explain, |> undoubtedly because I don't understand it! Would someone come to my |> rescue? Here's an example (assume that everything's been declared |> correctly): |> |> x = 3 * i ++; |> |> Book says that ++ has a higher precedence than *, and that ++ |> associates from R->L. That makes me think that ++ should be applied |> first, but I know it isn't. But ???? | |But ++ IS applied first! The key point here is that the RESULT of postfix ^^^^^^^^^^^^^^^^^ |++ is the value BEFORE incrementation, not that postfix ++ is somehow deferred ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |until later. Well, that still leaves me confused. If i has the value 7, it is 7 that is added to 3, so it seems to be that the ++ *is* deferred until later. Also, ++ has higher precedence than +, so why is the incrementation delayed until after the current value of i is used? I think we're getting close, though. :-) Thanks for the help. -- Peter Holsberg UUCP: {rutgers!}princeton!mccc!pjh Technology Division CompuServe: 70240,334 Mercer College GEnie: PJHOLSBERG Trenton, NJ 08690 Voice: 1-609-586-4800
edw@IUS1.CS.CMU.EDU (Eddie Wyatt) (02/23/88)
> > Well, that still leaves me confused. If i has the value 7, it is 7 that > is added to 3, so it seems to be that the ++ *is* deferred until later. > Also, ++ has higher precedence than +, so why is the incrementation > delayed until after the current value of i is used? > > I think we're getting close, though. :-) Thanks for the help. This really doesn't need a net rely, but .... You're having a problem understanding the semantic behind the post increment instruction. Think of it this way. a = 9 * i++; is equivalent to a = 9 * f(&i); int f(x) int *x; { int y; y = *x; *x = *x + 1; return(y); } and a = 9 * ++i; is equivalent to a = 9 * g(&i); int g(x) int *x; { int y; *x = *x + 1; y = *x; return(y); } Note that i++ evaluates (returns) the value of i before incrementing and ++i evaluates (returns) the value of i after incrementing, that's all. -- Eddie Wyatt e-mail: edw@ius1.cs.cmu.edu
scjones@sdrc.UUCP (Larry Jones) (02/24/88)
In article <234@mccc.UUCP>, pjh@mccc.UUCP (Peter J. Holsberg) writes: > In article <224@sdrc.UUCP> scjones@sdrc.UUCP (Larry Jones) writes: > |In article <226@mccc.UUCP>, pjh@mccc.UUCP (Peter J. Holsberg) writes: > |> > |> I find that associativity is a *very* difficult thing for me to explain, > |> undoubtedly because I don't understand it! Would someone come to my > |> rescue? Here's an example (assume that everything's been declared > |> correctly): > |> > |> x = 3 * i ++; > |> > |> Book says that ++ has a higher precedence than *, and that ++ > |> associates from R->L. That makes me think that ++ should be applied > |> first, but I know it isn't. But ???? > | > |But ++ IS applied first! The key point here is that the RESULT of postfix > ^^^^^^^^^^^^^^^^^ > |++ is the value BEFORE incrementation, not that postfix ++ is somehow deferred > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > |until later. > > Well, that still leaves me confused. If i has the value 7, it is 7 that > is added to 3, so it seems to be that the ++ *is* deferred until later. > Also, ++ has higher precedence than +, so why is the incrementation > delayed until after the current value of i is used? The result of i++ is the value of i. In addition, i gets incremented. You can think of i++ as being like inc(&i) where inc() is defined as: int inc(ip) int *ip; { int j = *i; *i = *i + 1; return j; } So, it's not the ++ operator that's defered, it's the side effect of the incrementation. You should also be aware that the incrementation can be defered for a long time - it may not happen until after the assignment. That's why i = i++ + 2; has no defined value -- you don't know whether the incrementation is done before or after the assignment. > I think we're getting close, though. :-) Thanks for the help. Hope this clears it up for good. ---- Larry Jones UUCP: uunet!sdrc!scjones SDRC MAIL: 2000 Eastman Dr., Milford, OH 45150 AT&T: (513) 576-2070 "When all else fails, read the directions."
bc@halley.UUCP (Bill Crews) (02/24/88)
In article <234@mccc.UUCP> pjh@mccc.UUCP (Peter J. Holsberg) writes: >In article <224@sdrc.UUCP> scjones@sdrc.UUCP (Larry Jones) writes: >|In article <226@mccc.UUCP>, pjh@mccc.UUCP (Peter J. Holsberg) writes: >|> >|> x = 3 * i ++; >|> >|> Book says that ++ has a higher precedence than *, and that ++ >|> associates from R->L. That makes me think that ++ should be applied >|> first, but I know it isn't. But ???? >| >|But ++ IS applied first! The key point here is that the RESULT of postfix > ^^^^^^^^^^^^^^^^^ >|++ is the value BEFORE incrementation, not that postfix ++ is somehow deferred > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >|until later. > >Well, that still leaves me confused. If i has the value 7, it is 7 that >is added to 3, so it seems to be that the ++ *is* deferred until later. >Also, ++ has higher precedence than +, so why is the incrementation >delayed until after the current value of i is used? Here is how to think of it. ++ performs two functions. It returns a value, and it has an effect on the variable to which it is applied. If the ++ precedes its operand: it increments the operand it returns the resulting value If the ++ succeeds its operand: it increments the operand it returns the value of the operand prior to the increment The other operators with which you are comparing it have only the functions of returning a value. This makes it confusing. But the act of returning the previous value is quite different from deferring the operator's effect. -bc -- Bill Crews Tandem Computers bc@halley.UUCP Austin, Texas ..!rutgers!im4u!halley!bc (512) 244-8350
jfh@killer.UUCP (The Beach Bum) (02/24/88)
In article <234@mccc.UUCP> pjh@mccc.UUCP (Peter J. Holsberg) writes: [ one explaination down, twenty five more to go ;-) ] >Well, that still leaves me confused. If i has the value 7, it is 7 that >is added to 3, so it seems to be that the ++ *is* deferred until later. >Also, ++ has higher precedence than +, so why is the incrementation >delayed until after the current value of i is used? > >I think we're getting close, though. :-) Thanks for the help. >-- >Peter Holsberg UUCP: {rutgers!}princeton!mccc!pjh This comes from a discussion which I believe was given in the document explaining the implementation of the portable C compiler. Consider ++ in it's two forms as a short-hand notation (don't believe it's true, just consider it. Flames to /dev/null) for: pre-fix: ++ X -> (X = X + 1) post-fix: X ++ -> ((X = X + 1), X - 1) So, the increment gets done, but, the value you get has been `adjusted' if you will. Try this: x = 5; printf ("3 * x ++ = %d\n", 3 * x ++); printf ("now x = %d\n", x); You should get 15 and 4. I suspect you expected 18 or 16 or something like that. [ I believe the context was that the compiler generated the trees using the long-hand, and then hoped to optimize to using increment instructions later. ] - John. -- John F. Haugh II SNAIL: HECI Exploration Co. Inc. UUCP: ...!ihnp4!killer!jfh 11910 Greenville Ave, Suite 600 "You can't threaten us, we're Dallas, TX. 75243 the Oil Company!" (214) 231-0993 Ext 260
dmt@ptsfa.UUCP (Dave Turner) (02/25/88)
In article <3466@killer.UUCP> jfh@killer.UUCP (The Beach Bum) writes: >In article <234@mccc.UUCP> pjh@mccc.UUCP (Peter J. Holsberg) writes: > > >pre-fix: ++ X -> (X = X + 1) >post-fix: X ++ -> ((X = X + 1), X - 1) > >Try this: > x = 5; > printf ("3 * x ++ = %d\n", 3 * x ++); > printf ("now x = %d\n", x); > >You should get 15 and 4. I suspect you expected 18 or 16 or something >like that. > I expected to get 15 and 6 (not 4) which is exactly what I got when I tried it. I've always found it to be useful to look at ++x and x++ and say: ++x increment x before using it in another expression in the same statement and x++ use the present value of x in any other expressions in this statement before incrementing x. X in the next statement will have the new value. There's more to be said but the above has been satisfactory for over 11 years. -- Dave Turner 415/542-1299 {ihnp4,lll-crg,qantel,pyramid}!ptsfa!dmt
cory@upba.UUCP (02/26/88)
(Sorry for posting instead of mailing, I couldn't find a path to mccc) > x = 3 * i ++; > > Book says that ++ has a higher precedence than *, and that ++ > associates from R->L. That makes me think that ++ should be applied > first, but I know it isn't. But ???? I can't really give you an understanding of associativity, as I don't know what you are missunderstanding. I could quote the definition, but I don't think that would solve your problem. I CAN try to help you understand the concept of precedence in expression evaluations. You seem to be confused on the use of "var ++". First, think of precedence as just putting a lot of parentheses everywhere. You know that ++ has a higher precedence than *, so lets rewrite your example with parentheses to show the precedence: x = ( 3 * ( i ++ ) ); Now lets evaluate the expression as it is written. First the inner-most parentheses are evaluated: EXP= ( i ++ ) This reads "get the value of i, increment i, and return the pre-increment value". The value of this part of the expression is the before-increment value of i. Now lets continue to the next level of parentheses: EXP= ( 3 * EXP ) This says multiply 3 times the value of the inner expression. (which was the pre-increment value of i) Finally: x = ( 3 * ( i ++ ) ); increments i by 1 unit of i's variable type and then assigns x the value of 3 times the pre-increment value of i. (guzzuntite) Hope this has been some help. -Cory ...!ihnp4!upba!cory (Cory Dekker @ United Phone Book Advertisers)| DISCLAIMER: Work: 1221 N St, Suite #800; Lincoln, NE 68508 {Ph: 402-476-2200}| My posting.. Home: 800 Foxcroft Ct, #188; Lincoln, NE 68510 {Ph: 402-483-7761}| MY opinions!
pjh@mccc.UUCP (Peter J. Holsberg) (02/26/88)
In article <230@sdrc.UUCP> scjones@sdrc.UUCP (Larry Jones) writes: |In article <234@mccc.UUCP>, pjh@mccc.UUCP (Peter J. Holsberg) writes: |> In article <224@sdrc.UUCP> scjones@sdrc.UUCP (Larry Jones) writes: |> |In article <226@mccc.UUCP>, pjh@mccc.UUCP (Peter J. Holsberg) writes: |> |> |> |> x = 3 * i ++; |> |> |> |> Book says that ++ has a higher precedence than *, and that ++ |> |> associates from R->L. That makes me think that ++ should be applied |> |> first, but I know it isn't. But ???? |> | |> |But ++ IS applied first! The key point here is that the RESULT of postfix |> ^^^^^^^^^^^^^^^^^ |> |++ is the value BEFORE incrementation, not that postfix ++ is somehow deferred |> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |> |until later. |> |> Well, that still leaves me confused. If i has the value 7, it is 7 that |> is added to 3, so it seems to be that the ++ *is* deferred until later. |> Also, ++ has higher precedence than +, so why is the incrementation |> delayed until after the current value of i is used? | |The result of i++ is the value of i. In addition, i gets incremented. You |can think of i++ as being like inc(&i) where inc() is defined as: | | int inc(ip) | int *ip; | { | int j = *i; | *i = *i + 1; | return j; | } | |So, it's not the ++ operator that's defered, it's the side effect of the ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |incrementation. You should also be aware that the incrementation can be |defered for a long time - it may not happen until after the assignment. |That's why i = i++ + 2; has no defined value -- you don't know whether the |incrementation is done before or after the assignment. | ???? Then what does the ++ operator-sans-side effect actually do??? It looks like it does nothing. -- Peter Holsberg UUCP: {rutgers!}princeton!mccc!pjh Technology Division CompuServe: 70240,334 Mercer College GEnie: PJHOLSBERG Trenton, NJ 08690 Voice: 1-609-586-4800
pjh@mccc.UUCP (Peter J. Holsberg) (02/26/88)
Dave, Your clear English-language statements reflect exactly the way I learned it, too. -- Peter Holsberg UUCP: {rutgers!}princeton!mccc!pjh Technology Division CompuServe: 70240,334 Mercer College GEnie: PJHOLSBERG Trenton, NJ 08690 Voice: 1-609-586-4800
al@gtx.com (0732) (02/26/88)
In article <4140@ptsfa.UUCP> dmt@ptsfa.UUCP (Dave Turner) writes: >I've always found it to be useful to look at ++x and x++ and say: > > x++ use the present value of x in any other expressions in this > statement before incrementing x. I hate to keep beating this horse, but the above statement is false. just see K&R p. 50. The problem the original questioner had [ essentially, "in a+b++ why does the addition appear to be done before the incrementation when the incrementation has higher priority?"] is just due to a confusion of syntax with semantics. syntactically, the ++ has higher priority and IS "applied" first. However, the semantics of applying ++ are defined in such a way as to defer the side effect. (exactly how long to defer the side effect is not well defined.) ---------------------------------------------------------------------- | Alan Filipski, GTX Corp, 2501 W. Dunlap, Phoenix, Arizona 85021, USA | | {ihnp4,cbosgd,decvax,hplabs,amdahl}!sun!sunburn!gtx!al (602)870-1696 | ----------------------------------------------------------------------
mike@arizona.edu (Mike Coffin) (02/27/88)
A simple way to understand the postincrement operator is to note that (x++) is equivalent to ((x += 1) - 1). -- Mike Coffin mike@arizona.edu Univ. of Ariz. Dept. of Comp. Sci. {allegra,cmcl2,ihnp4}!arizona!mike Tucson, AZ 85721 (602)621-4252