# Increment operator precedence

Discussion in 'C Programming' started by nl, Feb 15, 2008.

1. ### nlGuest

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

nl, Feb 15, 2008

2. ### raghuGuest

On Feb 15, 12:09 pm, nl <> wrote:
> 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?

raghu, Feb 15, 2008

3. ### Ian CollinsGuest

nl wrote:
> 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.

--
Ian Collins.

Ian Collins, Feb 15, 2008
4. ### Nick KeighleyGuest

On 15 Feb, 08:25, raghu <> wrote:
> On Feb 15, 12:09 pm, nl <> wrote:

> > 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.

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

--
Nick Keighley

Nick Keighley, Feb 15, 2008
5. ### Chris DollinGuest

nl wrote:

> 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 ...

--
"It was the dawn of the third age of mankind." /Babylon 5/

Hewlett-Packard Limited Cain Road, Bracknell, registered no:
registered office: Berks RG12 1HN 690597 England

Chris Dollin, Feb 15, 2008
6. ### John BodeGuest

On Feb 15, 2:09 am, nl <> wrote:
> 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.

John Bode, Feb 15, 2008
7. ### CBFalconerGuest

nl wrote:
>
> 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.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

CBFalconer, Feb 15, 2008
8. ### Jack KleinGuest

On Fri, 15 Feb 2008 07:22:16 -0800 (PST), John Bode
<> wrote in comp.lang.c:

> On Feb 15, 2:09 am, nl <> wrote:
> > 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

Jack Klein, Feb 16, 2008
9. ### Kenneth BrodyGuest

raghu wrote:
>
> On Feb 15, 12:09 pm, nl <> wrote:
> > 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:>

Kenneth Brody, Feb 17, 2008
10. ### John BodeGuest

On Feb 15, 10:30 pm, Jack Klein <> wrote:
> On Fri, 15 Feb 2008 07:22:16 -0800 (PST), John Bode
> <> wrote in comp.lang.c:
>
>
>
> > On Feb 15, 2:09 am, nl <> wrote:
> > > 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".
>

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?

John Bode, Feb 18, 2008
11. ### Richard TobinGuest

In article <>,
John Bode <> wrote:

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

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

Richard Tobin, Feb 18, 2008
12. ### Keith ThompsonGuest

John Bode <> writes:
> On Feb 15, 10:30 pm, Jack Klein <> wrote:
>> On Fri, 15 Feb 2008 07:22:16 -0800 (PST), John Bode
>> <> wrote in comp.lang.c:

[...]
>> > 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?

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.

--
Keith Thompson (The_Other_Keith) <>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson, Feb 18, 2008
13. ### Kenneth BrodyGuest

CBFalconer wrote:
>
> nl wrote:
> >
> > 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
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:>

Kenneth Brody, Feb 19, 2008
14. ### Guest

Kenneth Brody <> wrote:
>
> 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

, Feb 19, 2008