hi every one  :D
I have a portion a code in C as follow :


    int x;
    x=0;
    printf("%d %d\n",x++,x++);

    x=0;
    printf("%d %d\n",++x,++x);

    x=0;
    printf("%d %d\n",x++,++x);
   
    x=0;
    printf("%d %d\n",++x,x++);

    x=0;
    printf("%d\n",x++ +4 + ++x);


then complie and run it with vc++, and turbo c++ 3.0 , and this is the result:
in vc++

1 0
2 2
1 2
2 0
6


and in turbo c++

1 0
2 1
1 1
2 0
5


huh ?, i can understand the way turbo c++ evaluate value of x, but not with vc++.
is there any good way explain how vc++ result that ?
thanks.
Posted on 2008-05-25 06:28:04 by secmask
This is one of the questionable parts of C/C++... the compiler is free to re-order function argument evaluation as it sees fit. I'm too lazy to look up the relevant paragraph in The StandardTM, but it's not a compiler bug. The advice is to never use statements with side effects for function (or even worse, macro) arguments.

Also, statements like "array[i] = array[i++]" are unsafe.

Sucks? Yeah.
Posted on 2008-05-25 09:13:01 by f0dder
yes, i know, it's not safe to put a statement in (with ++, --,..) in side a function call, just try to understand why.
thanks f0dder.
Posted on 2008-05-26 01:15:37 by secmask
Stupid interpreters written by Stupid people who can't read or at least stick to Stupid standards.
They exist to make life interesting.
Posted on 2008-05-26 05:05:38 by Homer
VC is correct when it procudes "6" (turbo c++ is not correct here), but it's not correct with "2 2" and "1 2" -- these two should be "2 1" and "1 1" as turbo c++ produces.

I personally avoid ANY "++" or "--" except in single statements (like: "k++;") -- saves me a lot of trouble ;)
Posted on 2008-05-26 07:47:03 by ti_mo_n
timon, VC isn't in error - the standard doesn't make guarantees on evaluation order of function arguments. This is something that can give some pretty nasty bugs, just like depending on the order of temporary object creation (which isn't defined, either).
Posted on 2008-05-26 08:29:44 by f0dder
but with this


    x=0;
    y = (x++ *2)+ 3 + ++x;
    printf("%d\n",y);


the result is 6, seem that the parentheses does not make x++ *2 more priority.
i think it should be: (0 * 2) +3 + 2 = 5. as the article at here http://www.cplusplus.com/doc/tutorial/operators.html.
Posted on 2008-05-26 10:23:39 by secmask
I would have expected it to be  (0 * 2) + 3 + 1 = 4, since it's my understanding that postfix is incremented at the end of the entire statement... VS2008 produced 6, GCC4.1 produces 4. Guess it might be time to re-read parts of The Standard to see what it really says.

http://parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.15
and some more:

The order in which operands in an expression are evaluated is unspecified in C++. The only guarantee is that they will all be completely evaluated at the next sequence point.


Unfortunately, I only have Stroustrup's "The C++ Programming Language", not the ISO C++ reference, so I can't look up the exact paragraph.

Just accept that evaluation order is undefined in cases like this, and don't write such horrid code :)
Posted on 2008-05-26 17:52:12 by f0dder

but with this


    x=0;
    y = (x++ *2)+ 3 + ++x;
    printf("%d\n",y);


the result is 6, seem that the parentheses does not make x++ *2 more priority.
i think it should be: (0 * 2) +3 + 2 = 5. as the article at here http://www.cplusplus.com/doc/tutorial/operators.html.


One of the major misunderstandings is the difference between "combinatorial" or "combinational" priority and "evaluation" priority. Every time you see operator priority, it's always about which way to combine values, rather than which order they are evaluated. Out of necessity, the order of nested subexpressions is partially defined. In the case of separate, independent subexpressions, languages may or may not define evaluation order.

The difference is accentuated when you are dealing with function calls.

For example, you have the following C/C++ statement.

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

The left-to-right priority rule will only tell you that the results of f(x) and g(x) are combined before combining with the results of h(x). However, if allowed, the compiler is free to call h(x) and save it in a temporary location before calling f(x) and g(x) and combining their results. If the three functions do not share global variables or system resources (such as I/O), the results will be the same regardless of "evaluation" order.

In the quoted code, (x++ *2) and ++x are separate, independent subexpressions. They are not nested with each other. And the C and C++ languages allow either to be evaluated first.
Posted on 2008-05-27 16:04:56 by tenkey
This is a shortcoming that has always bothered me about C, but usually solvable with parenthesis in the right places.
Posted on 2008-05-31 00:07:10 by iblis
iblis: parenthesis won't help you with this specific issue at all... they only help you wrt. "mathy" evaluation order, they don't protect you from side effects from writing nasty code :)
Posted on 2008-05-31 04:28:37 by f0dder
Yeah I know.  I should have been more clear; I was referring to the order of evaluation problem, not the ++/-- problem.
The only time I ever use increment operators is when the behavior is defined, like in for loops and such.
Or if it's just on one line.
Posted on 2008-05-31 04:41:43 by iblis
Order of evaluation is pretty well-defined, so you don't need parenthesis. I tend to add them anyway, though, since it makes more complex expressions easier to read at a glance, imho :)
Posted on 2008-05-31 04:46:59 by f0dder
I didn't know that it's well defined.  I always assumed (and vaguely remember reading about it) that there was an order of evaluation issue with C because I would always end up with the unexpected values whenever I would omit parenthesis.

Maybe I just need to revisit some of my dusty old fundamental C books.  :)
Posted on 2008-05-31 04:53:30 by iblis
Well, I thought the order was well defined as well, though I always used parentheses too, since they made things a hell of a lot easier to read.
Posted on 2008-05-31 10:37:15 by Bobbias