?
Solved

pre/post increment

Posted on 2003-02-25
5
Medium Priority
?
263 Views
Last Modified: 2010-04-15
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
Comment
Question by:chirilabogdan
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
5 Comments
 
LVL 45

Expert Comment

by:Kent Olsen
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

by:
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

by:c_wongsiriprasert
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 45

Expert Comment

by:Kent Olsen
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

by:darlingm
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?

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

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question