Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
Solved

# pre/post increment

Posted on 2003-02-25
Medium Priority
267 Views
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?

0
Question by:chirilabogdan
• 2
• 2

LVL 46

Expert Comment

ID: 8016262

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

LVL 1

Accepted Solution

darlingm earned 300 total points
ID: 8016336
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

Expert Comment

ID: 8016406
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

LVL 46

Expert Comment

ID: 8016494

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

LVL 1

Expert Comment

ID: 8017154
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?

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

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
###### Suggested Courses
Course of the Month14 days, 22 hours left to enroll