Path: utzoo!mnetor!uunet!mcvax!tuvie!rcvie From: rcvie@tuvie (ELIN Forsch.z.) Newsgroups: comp.lang.c Subject: Re: Autoincrement question Message-ID: <548@tuvie> Date: 7 Dec 87 10:00:58 GMT References: <1507@ogcvax.UUCP> Organization: TU Vienna EDP-Center, Vienna, AUSTRIA Lines: 58 In article <1507@ogcvax.UUCP>, schaefer@ogcvax.UUCP (Barton E. Schaefer) writes: > (I realize this might be similar to another question asked recently, but ...) > > Another student here at OGC recently came to me with a question about the > C autoincrement operator. The following program is representative of the > code he wrote, which did not do what he expected: > > struct foo { struct foo *tmp; char junk[32]; } foolist[4]; > > main () > { > struct foo *bar; > > bar = foolist; > /* Do something with bar */ > bar->tmp = bar++; /* This is the problem line */ > /* Do something else */ > } > This is really dangerous programming. The points where the left and where the right "bar" are evaluated are implementation defined. The problem is similar to another one, which a friend of mine had some time ago. He tried to pack as much as possible into the control part of a while loop using the following statement: while (a[i]=b[i++]) ; Things were even worse here, as the program behaved even differently depending on whether it was compiled with the optimization option or not. Non optimized everything worked as expected but in the optimized version only for the first assignment "i" was incremented after the assignment, for all the following assignments it was incremented after the evaluation of "b[i]" but before the assignment. Nevertheless this behaviour was in the sense of both K&R and ANSI. The only thing you can trust on, is that the *operand* of the increment operator is evaluated before its incrementation. One way to achieve the desired behaviour is, as you suggested yourself, to write: > What he really wanted was the equivalent of > bar->tmp = bar; > bar++; and not (for the same reasons stated above): > (bar++)->tmp = bar; If there is any necessity to have the whole semantic in one *expression*, use the comma operator, as bar->tmp = bar, bar++; This operator *guarantees* the sequential evaluation of its operands from left to right. In real life: Dipl.Ing. Dietmar Weickert ALCATEL Austria - ELIN Research Center Floridusg. 50 A - 1210 Vienna / Austria