• C

pre/post increment

Under Solaris 5.8

#include<stdio.h>
int main()
{
     int k;
     
     k = 1;
     k = k++ + ++k;
     printf("%d", k);
     return 0;
}
At:
cc file.c  => result is 5
gcc file.c => result is 2

what result is good?

chirilabogdanAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Kent OlsenData Warehouse Architect / DBACommented:

I must admit that I never envisioned the statement:

k = k++ + ++k;


---------------------------

k = k++ + ++k;

k = (k+1) + (1+k);

k = (1+1) + (1+1);

k = 4

---------------------------

k = ((k++)++) + k;

k = ((k+1)+1) + k;

k = ((1+1)+1) + 1;

k = 4;

---------------------------

k = k + (++(++k));

k = k + (1+(1+k));

k = 1 + (1+(1+1));

k = 4;


No matter how the parsers evaluate the expression, it looks like both have their own problem....


Kdo


0
darlingmCommented:
Hi chirilabogdan,
k++ (post increment) means increment k after any assignment operation that it is involved in.
++k (pre incremenet) means increment k before any assignment operation that it is involved in.

An assignment operation is the = operator, the last operator to be executed, so we can rewrite your line of code of
k = k++ + ++k
as seperate lines of code (I'll seperate by a ";")
k = k + ++k ; k = k + 1 {substituted k++ for an operation after this assignment}
k = k + 1 ; k = k + k ; k = k + 1 {substituted ++k for an operation before this assignment}

Depending on your interpretation, you can execute these statements three different ways.

(first) interpretation is that we execute these in serial, truly treating each "new" line of code as seperate.
k = k + 1 ; k = k + k ; k = k + 1
is executed as
k = 1 + 1 (k = 2) ; k = 2 + 2 (k = 4) ; k = 4 + 1 (k = 5)

(second) interpretation is to fully substitute as much as possible, then execute the statements.  
k = k + 1 ; k = k + k ; k = k + 1
is setup as
k = 1 + 1 ; k = 1 + 1 ; k = k + 1
and is then executed as
k = 2 ; k = 2 ; k = 2

(third) interpretation is that we could in parallel run the statements, using initial values before your line of code as input into each parallel calculation
This is a slightly different spin on the second possibility, listed above.  It might be a parallel programming problem rather than an improper full substitution before execution problem though (whether or not it runs on parallel processors is somewhat irrelevant, but would be interesting to know).

My feeling is that the first possibility is correct, the second one is incorrect, and the third one is incorrect.

The compiler is going to treat a line of code like this as a stack, following the rules of operations, to generate the actual machine code to put in your executable.  The actual executable won't be using a stack at runtime to figure out what to do, it will be all pre-processed into simpler calculations.  No calculations should be done in the compiler stage in the case of your line of code, that should all be left to do at runtime, which would allow the first possibility to occur.  The compiler should only handle calculations if it sees something like (k = 3 + 4)... There is no reason why it can't change 3 + 4 to a 7, but if there's a variable there, it should leave it alone even if it sees it is declared as 1.

What version of cc and gcc are you running?  Are you on a parallel processor machine?

Under gcc 2.95.3 (FreeBSD v4.6.2) and gcc 3.2.1 (FreeBSD v5.0), result is 5.  I would suggest this as more evidence that 2 is an incorrect answer.

I would try upgrading to a more recent gcc version if possible.  Or you could just recognize that you can't write the line of code that way because the compilers you are using have a bug in them, and rewrite the line of code into seperate lines of code to have it act the way you want... This is frustrating when this happens, but the code needs to operate deterministically.  Sometimes you have no choice.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
c_wongsiriprasertCommented:
Non of  the result is good because this  specified in C standard as an
undefined behavior which mean each compiler can produce any result as they
want.

The code is good for study C but  don;t put it in any production code.
Don't write the code that you don't sure about the result.
0
Kent OlsenData Warehouse Architect / DBACommented:

I'd written that first example as an "intuitively, this is what one might think should happen".  Then instead of veering off into the "this is what really should or could happen" I thought, "this is pretty weird -- what happens if you regroup the '+' symbols?"

Next thing you know, I'd completely missed that left turn at Albuquerque.  ;)

Obvious, if (++k) is evaluated/executed prior to (k++) the results will be different.


Good catch, darlingm.

Kdo
0
darlingmCommented:
I spoke with someone who has experience with compiler design.

I'm going to have to back the answer by c_wongsiriprasert.

----------
#include<stdio.h>

void f(int a, int b) {
    printf("a = %d b = %d\n", a, b);
}

int main() {
    int k = 1;

    f(++k, ++k);
}
----------

output is "a = 3 b = 2"

weird, huh?

with f(k++, k++) instead

output is "a = 2 b = 1"

again, weird.

gcc seems to be doing the line from right to left...

I'm going to, at this point, strongly recommend only using one pre/post increment operater per line of code -- due to the ambiguity of compiler implementation.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.