Re: [LIP] Undefined behaviour ?
Bhaskar Dutta <[email protected]>
| Newsgroups | gmane.user-groups.linux.india.programmers |
|---|---|
| Organization | Bhaskie Inc. |
| Message-ID | <[email protected]> |
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Wednesday 29 Oct 2003 8:24 pm, you wrote: > ----- Original Message ----- > From: "Mithun Bhattacharya" <inzoik-/[email protected]> > ----------------- > #include <stdio.h> > main() { > int i = 4; > /* int j = i+++++i+i+++++i; */ > /* int j = i++ + ++i + i++ + ++i ; */ > int j = (i++)+(++i)+(i++)+(++i); > printf("%d\n", j); > } > ----------------- Hi, Firstly, let me remind you something .... such C code should be totally avoided at any cost. They may come in sample C tests to check your know-how (I don't know why they still do as these Q's have become totally banal) and you should definitely know what's the mystery behind it...but never try to implement such code for god's sake... you will be shooting yourself on the foot! Temporal precedence is not defined even by K&R and it is on the compiler designers to deal with the matter. As such you get strange results with different compilers and various optimizations. > > The above peice of code has three initialization of j out of which only > the last two works with gcc 3.2.2 > I am not sure why gcc fails on the first but the error message "invalid > lvalue in increment" doesnt somehow seem right. I dont see the problem > with j and if i++ is being considered a lvalue then why so ? gcc is correct. There is a _CLEAR_ invalid lvalue when the increment operator is tried 2nd time. Such code is not allowed. First increment puts value in temporary register and there is no lvalue...so on what will you perform the 2nd increment ? > After compillation I get a value of 21 - how that value is coming up I > have no idea. VC compiles all three syntaxes I believe but returns 21 > in debug mode and 24 in release mode. > From my limited knowledge I can think of two ways to process the > expression. > > (i++) + (++i) + (i++) + (++i) = (4++) + (++5) + (6++) + (++7) = 4 + 6 + > 6 + 8 = 24 > > (i++) + (++i) + (i++) + (++i) = (4++) + (++4) + (5++) + (++5) = 4 + 5 + > 5 + 6 = 20 > > Obviously none of them match what gcc is coming up with. Could someone > please explain what is happening here ? > > Mithun > The results are perfectly sane. You are missing the concept of stacks used in temporary storage. The values are applied in reverse order by popping from the stack. Figure this out: (i++) + (++i) + (i++) + (++i) = (5++) + (++5) + (5++) + (++4) = 5 + 6 + 5 + 5 = 21 voila...that's what the compiler shows! (a little strange because of register optimization..) The result of release mode is 24 because the temporal precedence is strictly followed without assumptions by the compiler: (usage of lvalue after 5 is post-incremented) 7++ + ++6 + 5++ + ++4 == 7+7+5+5 ==24 Now you see that's the reason we shouldn't use such code in real apps. The compiler writers in various platforms use their own techniques to optimize code so registers are used is different ways and assembly code is re-ordered. Hence certain instructions like i++ may be done later than expected because of rearrangement of 3 field code. This happens because we don't specify lvalues particularly and leave it to the compiler to figure out. This leads to indefinite behavior. I hope I am clear about the matter. Feel free to question anything if I am wrong. Regards, Bhaskar. - -- - --------------------------- Bhaskar Dutta <[email protected]> Key fingerprint = AA56 1EB5 D7E8 DD9C 298E 8F4D 375F D416 01D5 671C - --------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE/oArYN1/UFgHVZxwRAiZ+AJ46KzZ6FwaNg36Kz8VDf8aKhc5ZRACeOoMp DT67eKy/UPD+zUALnVnBLC8= =Qkk9 -----END PGP SIGNATURE----- ------------------------------------------------------- This SF.net email is sponsored by: SF.net Giveback Program. Does SourceForge.net help you be more productive? Does it help you create better code? SHARE THE LOVE, and help us help YOU! Click Here: http://sourceforge.net/donate/