Increment operator precedence

N

nl

Hi, I am confused about the order of operation for the increment
operater ++. I wrote the program below trying to clear my doubts, but
it just got me more confused. For example, in the second case, I
thought that ++x will increment x to 2. and since y = 3, that makes z
= 2 + 3 =5. However the result shows that z =4.

Would greatly appreciate any help.

#include <stdio.h>

int main(void)
{
int x=1, y=1, z=0;

z = x++ +( y += x++) ;

printf("\n\n%d %d %d\n\n", x, y, z);
x=1, y=1, z=0;

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

x=1, y=1, z=0;

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

x=1, y=1, z=0;
z = ++x +( y += ++x) ;

printf("\n\n%d %d %d\n\n", x, y, z);
return 0;
}


The results:

2 2 3


2 3 4


3 3 5


3 4 6
 
R

raghu

Hi, I am confused about the order of operation for the increment
operater ++. I wrote the program below trying to clear my doubts, but
it just got me more confused. For example, in the second case, I
thought that ++x will increment x to 2. and since y = 3, that makes z
= 2 + 3 =5. However the result shows that z =4.

Would greatly appreciate any help.

#include <stdio.h>

int main(void)
{
    int x=1, y=1, z=0;

    z = x++ +( y += x++) ;

    printf("\n\n%d %d %d\n\n", x, y, z);
    x=1, y=1, z=0;

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

    x=1, y=1, z=0;

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

    x=1, y=1, z=0;
    z = ++x +( y += ++x) ;

    printf("\n\n%d %d %d\n\n", x, y, z);
    return 0;

}

The results:

2 2 3

2 3 4

3 3 5

3 4 6

The results are correct.

Where did u find the problem?
 
I

Ian Collins

nl said:
Hi, I am confused about the order of operation for the increment
operater ++. I wrote the program below trying to clear my doubts, but
it just got me more confused. For example, in the second case, I
thought that ++x will increment x to 2. and since y = 3, that makes z
= 2 + 3 =5. However the result shows that z =4.

Would greatly appreciate any help.

#include <stdio.h>

int main(void)
{
int x=1, y=1, z=0;

z = x++ +( y += x++) ;
The above invokes undefined behaviour, you can't increment x twice
without a sequence point.
 
N

Nick Keighley

The results are correct.

no. All the instances in the example invoke Undefined Behaviour
so the implementation can do whatever it pleases. In a sense *any*
result is "correct". I'd prefer to say expecting any particular
result is wrong.
Where did u find the problem

please don't use "txt" speak in your posts.
 
C

Chris Dollin

nl said:
Hi, I am confused about the order of operation for the increment
operater ++. I wrote the program below trying to clear my doubts, but
it just got me more confused. For example, in the second case, I
thought that ++x will increment x to 2. and since y = 3, that makes z
= 2 + 3 =5. However the result shows that z =4.

Would greatly appreciate any help.

#include <stdio.h>

int main(void)
{
int x=1, y=1, z=0;

z = x++ +( y += x++) ;

Not allowed.
printf("\n\n%d %d %d\n\n", x, y, z);
x=1, y=1, z=0;

z = x++ +( y += ++x) ;

Not allowed.
printf("\n\n%d %d %d\n\n", x, y, z);

x=1, y=1, z=0;

z = ++x +( y += x++) ;

Not allowed.
printf("\n\n%d %d %d\n\n", x, y, z);

x=1, y=1, z=0;
z = ++x +( y += ++x) ;

(All together now:) Not allowed.
printf("\n\n%d %d %d\n\n", x, y, z);
return 0;
}

All four statements lead to Undefined Behaviour: C does not specify and
does not care how the implementation chooses to implement them. Taking
z = x++ +( y += x++) ;

as the example, we see it tries to update `x` twice in the same
statement. This is /specifically/ not allowed by the Standard [1].
(I believe this is to allow implementors enough slack to do efficient
code generation, but it also eliminates some chances of confusion.)

In the expression `a + b`, it's not specified whether `a` or `b` is
evaluated first. In the expressions `a++` and `++a, it's not specified
when `a` is incremented, so long as its done by the end of the statement.
In the expression `a = b`, it's not specified whether (the address of)
`a` is evaluated before (the value of) `b`. So even without the Thou
Shalt Not for multiple updates of `x`, in
int x=1, y=1, z=0;
z = x++ +( y += x++) ;

`x`, `y`, and `z` could end up with all sorts of different values;
that in fact they are allowed to end up with /any values at all/,
or an exception could be thrown [2], or /other/ variables could
be updated, is worse but not concept-breakingly worse.

[1] Actually the Standard talks about "sequence points", which are
the points in an expression where any side-effects of the
expression must have been committed; end-of-statement is the
most common, but the others are the end of the left operand of
`&&`, `||`, `?:`, the comma-operator `,` (NOT the argument-
separator `,`),, and function-call.

[2] Yes, C doesn't have exceptions -- but Undefined Behaviour takes
you outside where C cares ...
 
J

John Bode

Hi, I am confused about the order of operation for the increment
operater ++. I wrote the program below trying to clear my doubts, but
it just got me more confused. For example, in the second case, I
thought that ++x will increment x to 2. and since y = 3, that makes z
= 2 + 3 =5. However the result shows that z =4.

As others have pointed out, attempting to update the same object more
than once between sequence points results in undefined behavior; *any*
result is considered "correct", because the standard places no
restrictions on the compiler.

Any expression of the forms

x = x++
i++ + i++
a = i++ (or a[i++] = i)

will result in undefined behavior.

Some things to remember when using the autoincrement and autodecrement
operators:

1. Both a++ and a-- evaluate to the current value of a, ++a evaluates
to the current value of a + 1, --a evaluates to the current value of a
- 1, and as a *side effect*, the value of a is updated. Note that the
side effect does not have to be applied immediately after the
expression has been evaluated. Depending on the compiler, side
effects may be deferred until all other expressions have been
evaluated, or until some subset of expressions have been evaluated.
For example, given the statement

z = a++ * --b;

z will get the current value of a multiplied by the current value of
b-1. However, exactly when a and b get updated is not fixed; both may
be updated immediately after they're evaluated, they may be updated
only after both have been evaluated, or they may be updated after z
has been assigned. The only rule is that both have been updated by
the end of the statement. Any of the following are possible:

t1 <- a // a and b are updated immediately after evaluation
a <- a + 1
t2 <- b - 1
b <- b - 1
z <- t1 * t2

or

t1 <- a // a and b are updated at the end
t2 <- b - 1
z <- t1 * t2
a <- a + 1
b <- b - 1


2. a-- evaluates to the current value of a, --a evaluates to the
current value of a - 1, and as a *side effect*, the value of a is
decremented. Same disclaimer as above about when the side effect is
applied.

3. Precedence and order of evaluation are two different things.
Given the expression

a() * b() + c()

precedence rules require that the result of a() be multiplied by the
result of b() before the result of c() is added. However, there's no
guarantee that a() will be *evaluated* before b() or c(). The
compiler may arrange things so that c() is called *first*, and its
result is stored until a() and b() have been evaluated and their
results multiplied together. Similarly, with an expression like

a++ * b++ + c++

there's no guarantee that a has been evaluated or incremented before
either c or b have been evaluated.
 
C

CBFalconer

nl said:
Hi, I am confused about the order of operation for the increment
operater ++. I wrote the program below trying to clear my doubts,
but it just got me more confused. For example, in the second
case, I thought that ++x will increment x to 2. and since y = 3,
that makes z = 2 + 3 =5. However the result shows that z =4.

Would greatly appreciate any help.

#include <stdio.h>

int main(void) {
int x=1, y=1, z=0;

z = x++ +( y += x++) ;
^ ^
[1] [2]

Why do you assume that [1] precedes [2], or that [2] precedes [1]?
If you read the C standard you will see that the expression is
undefined in standard C. Any result meets the requirements.
 
J

Jack Klein

Hi, I am confused about the order of operation for the increment
operater ++. I wrote the program below trying to clear my doubts, but
it just got me more confused. For example, in the second case, I
thought that ++x will increment x to 2. and since y = 3, that makes z
= 2 + 3 =5. However the result shows that z =4.

As others have pointed out, attempting to update the same object more
than once between sequence points results in undefined behavior; *any*
result is considered "correct", because the standard places no
restrictions on the compiler.

Any expression of the forms

x = x++
i++ + i++
a = i++ (or a[i++] = i)

will result in undefined behavior.

Some things to remember when using the autoincrement and autodecrement
operators:


ITYM "preincrement" and "predecrement", rather than "autoincrement"
and "autodecrement".

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
K

Kenneth Brody

raghu said:
Hi, I am confused about the order of operation for the increment
operater ++. I wrote the program below trying to clear my doubts, but [...]
z = x++ +( y += x++) ; [...]
z = x++ +( y += ++x) ; [...]
z = ++x +( y += x++) ; [...]
z = ++x +( y += ++x) ; [...]
The results:

2 2 3

2 3 4

3 3 5

3 4 6

The results are correct.

Well, "correct" in the sense that "undefined behavior can result
in anything happening, including what you thought you meant to do".
Where did u find the problem?

I don't believe that Mr. Thant was looking for any problems.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
J

John Bode

As others have pointed out, attempting to update the same object more
than once between sequence points results in undefined behavior; *any*
result is considered "correct", because the standard places no
restrictions on the compiler.
Any expression of the forms
x = x++
i++ + i++
a = i++ (or a[i++] = i)

will result in undefined behavior.
Some things to remember when using the autoincrement and autodecrement
operators:

ITYM "preincrement" and "predecrement", rather than "autoincrement"
and "autodecrement".


I've always used "auto*crement" when referring to both pre- and
postfix forms, and IINM the rules I listed apply to both.

Am I abusing terminology again?
 
R

Richard Tobin

ITYM "preincrement" and "predecrement", rather than "autoincrement"
and "autodecrement".
[/QUOTE]
I've always used "auto*crement" when referring to both pre- and
postfix forms [...]
Am I abusing terminology again?

The terms "autoincrement" and "autodecrement" were used for register
address modes on the PDP-11. That made sense: they were modes for
calculating an address, that had an added side effect of incrementing
or decrementing.

Carrying the terms over to the analogous C operators is natural, even
if there is less need to emphasise any automatic-ness.

-- Richard
 
K

Keith Thompson

John Bode said:
I've always used "auto*crement" when referring to both pre- and
postfix forms, and IINM the rules I listed apply to both.

Am I abusing terminology again?

In my experience, the term autoincrement refers to a certain
addressing mode on the PDP-11 and other architectures which causes the
address stored in a CPU register to be automatically incremented when
you access memory through it.

The terms {pre,post}{in,de}crement seems clearer and more applicable
to the C "++" and "--" operators.
 
K

Kenneth Brody

CBFalconer said:
Hi, I am confused about the order of operation for the increment
operater ++. I wrote the program below trying to clear my doubts,
but it just got me more confused. For example, in the second
case, I thought that ++x will increment x to 2. and since y = 3,
that makes z = 2 + 3 =5. However the result shows that z =4.

Would greatly appreciate any help.

#include <stdio.h>

int main(void) {
int x=1, y=1, z=0;

z = x++ +( y += x++) ;
^ ^
[1] [2]

Why do you assume that [1] precedes [2], or that [2] precedes [1]?
If you read the C standard you will see that the expression is
undefined in standard C. Any result meets the requirements.

It seems to be a not-so-uncommon misconception that expressions
inside of parentheses must be performed before anything outside
of parentheses. They appear to base this on cases such as:

a * ( b + c )

where the value of the "b + c" expression must be evaluated before
the multiplication takes places. Of course, nothing requires that
this be taken to mean that "a" cannot be evaluated first. For
example, a stack-based machine may generate:

push a
push b
push c
add
mult

In fact, for cases such as:

a + ( b - c )

it is not even necessary that "b - c" be evaluated separately, as
the expression is identical to:

( a + b ) - c

and the "as-if" rule permits the compiler to treat the two the
same.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
L

lawrence.jones

Kenneth Brody said:
In fact, for cases such as:

a + ( b - c )

it is not even necessary that "b - c" be evaluated separately, as
the expression is identical to:

( a + b ) - c

and the "as-if" rule permits the compiler to treat the two the
same.

Only if the compiler can be certain that a+b won't overflow or that
overflow is silent and invertible (or that b-c will overflow, in which
case all bets are off).

-Larry Jones

What a stupid world. -- Calvin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top