how do increment operations work

P

pai

hi..

I have a simple doubt about increment operators..

Can any one tell me what is really happening..

Eg:
int i=0,ans;

( ans = ++i ++i // This
gives error while compiling )

ans = ++i + +i ;
printf(" %d %d ",ans,i); // it prints 2 1

i=0;
ans = ++i + ++i ;
printf(" %d %d ",ans,i); // it prints 4 2

i=0;
ans = ++i + ++i + ++i;
printf(" %d %d ",ans,i); // it prints 7 3

How do 4 and 7 came can any one explain...

Thanks
Pai
 
K

Keith Thompson

pai said:
I have a simple doubt about increment operators..

I think you mean "question", not "doubt". The words may be synonymous
in your dialect of English, but they mean different things to most of
us.
Can any one tell me what is really happening..

Eg:
int i=0,ans;

( ans = ++i ++i // This
gives error while compiling )

ans = ++i + +i ;
printf(" %d %d ",ans,i); // it prints 2 1

i=0;
ans = ++i + ++i ;
printf(" %d %d ",ans,i); // it prints 4 2

i=0;
ans = ++i + ++i + ++i;
printf(" %d %d ",ans,i); // it prints 7 3

How do 4 and 7 came can any one explain...

Your indentation is excessive and inconsistent, making it difficult to
read your code.

The C FAQ is at <http://www.c-faq.com/>. Read question 3.2. Then
read the rest of section 3. Then read the rest of the FAQ.
 
P

pai

hi..

Sorry for not having a clear english dialect.
I am not able to understand how is the increment works in program 1
and in program 2 why there is a compile error.

here is the code..

---------------------------------------
Program 1
-------------------------------------
main(){

int i=0,ans;

ans = ++i + +i ;
printf(" %d %d \n",ans,i);

i=0;
ans = ++i + ++i ;
printf(" %d %d \n",ans,i);

i=0;
ans = ++i + ++i + ++i;
printf(" %d %d \n",ans,i);

}

The result
2 1
4 2
7 3

----------------------------------------
program 2
------------------------------------------------
Another program is

main(){
int i=0,ans;

ans = ++i ++i ;
printf(" %d %d \n");

}

This gives compile error
test1.c:4: In function `main':
test1.c:4: error: invalid lvalue in increment
test1.c:9: error: syntax error before "i"



Thanks
Pai
 
V

Vladimir S. Oka

pai said:
hi..

I have a simple doubt about increment operators..

Can any one tell me what is really happening..

Eg:

Your code is incomplete, and horribly difficult to read with that much
indentation (one reason may be using TABs in the original file, which
is almost always a bad idea).

You're missing:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int i=0,ans;

These are better put on separate lines, or at least horizontally spaced.
Choose from:

int i = 0, ans;

and

int i = 0;
int ans;
( ans = ++i ++i //
This
gives error while compiling )

This is not a legal C comment (nor are C++ style ones, at least for on
compiler).

Of course this is a syntax error. Sequence <expression1> <whitespace>
<expression2> is not legal in C. You have `++i` as both expression 1
and 2. If you expected something different (and I can't see what that
might have been), keep in mind that compiler follows `maximum munch`
rule, i.e. it reads the code sequentially and tries to make sense of
the longest possible legal sequence of characters. In your case these
are both `++i`s, but stringing them together does not make sense.
ans = ++i + +i ;
printf(" %d %d ",ans,i); // it prints 2 1

This is undefined behaviour. The `++i` bit can be executed at any time
during the evaluation of the expression (but before the sequence point
marked with `;` in your case, and after the previous one, which in your
case is the previous `;`). The same holds true for taking the value of
`i` for the second part of your expression (`+` in `+i` is unary plus,
which does exactly the same as +2 does in mathematics, i.e. nothing
much). Your compiler has chosen to first do `++i` then take value of
`i`, and evaluate expression as 2. It might have decided to do it the
other way around, and give you 0.
i=0;
ans = ++i + ++i ;
printf(" %d %d ",ans,i); // it prints 4 2

U.B. here as well, and your compiler chooses to be consistent and first
do both `++i`s, then perform addition, and give you 4 as a result.
i=0;
ans = ++i + ++i + ++i;

Same again here, but now the compiler apparently decides to deal with
the first two `++i`s first, add the results, only then perform the
third `++i`, and add that to the running total.

NB, all these are just my double-guessing what your compiler decided to
do on this particular occasion. Next week it may decide to do something
entirely different. Do not do these things (and do not rely on what
this compiler does when switching to a different one).
printf(" %d %d ",ans,i); // it prints 7 3

It is actually lucky that you get anything out of this program, as you
did not terminate the printf() with '\n' to force flushing of stdout.

You've missed these as well:

return 0;
}
How do 4 and 7 came can any one explain...

As Keith pointed out elsethread reading the C FAQ at
http://www.c-faq.com/ (maybe even the whole thing, not just 3.2 he
suggested) would help you know the answers to such questions (or even
not to try to ask them of the compiler at all) immediately.

Cheers

Vladimir
 
F

Fred Kleinschmidt

pai said:
hi..

I have a simple doubt about increment operators..

Can any one tell me what is really happening..

Eg:
int i=0,ans;

( ans = ++i ++i // This
gives error while compiling )

ans = ++i + +i ;
printf(" %d %d ",ans,i); // it prints 2 1

i=0;
ans = ++i + ++i ;
printf(" %d %d ",ans,i); // it prints 4 2

i=0;
ans = ++i + ++i + ++i;
printf(" %d %d ",ans,i); // it prints 7 3

How do 4 and 7 came can any one explain...

Thanks
Pai

Read the FAQs! This is one of the most common questions.
Basically, you can't auto-increment a variable more than once between
control points. So any statement that increments a variable more than once
leads to undefined behavior.
 
J

John Bode

pai said:
hi..

I have a simple doubt about increment operators..

Can any one tell me what is really happening..

Eg:
int i=0,ans;

( ans = ++i ++i // This
gives error while compiling )

As well it should.
ans = ++i + +i ;
printf(" %d %d ",ans,i); // it prints 2 1

i=0;
ans = ++i + ++i ;
printf(" %d %d ",ans,i); // it prints 4 2

i=0;
ans = ++i + ++i + ++i;
printf(" %d %d ",ans,i); // it prints 7 3

How do 4 and 7 came can any one explain...

Thanks
Pai

Any expression of the form i = i++, i = j++ + j++, a = i++, and
f(i++, i++) will invoke undefined behavior, meaning the compiler is
under no obligation to yield a correct or meaningful result, so trying
to figure out exactly *how* those results came about is often a futile
exercise.

The reason these expressions are undefined is because you are
attempting to read and modify an object more than once between
successive sequence points. Because of the way the autoincrement and
autodecrement operators work, there's no guarantee that the side effect
will be applied immediately after the expression is evaluated; it's
possible for the compiler to defer applying side effects until after
some or all of the expressions have been evaluated. In the last case,
it *looks* like the compiler is doing this:

1. evaluate ++i -> 1
2. add 1 to i (1)
3. evaluate ++i -> 2
4. add 1 to i (2)
5. evaluate 2 + 2 -> 4
6. evaluate ++i -> 3
7. add 1 to i (3)
8. evaluate 4 + 3 -> 7
9. assign 7 to ans

Or it could be doing something else completely. Such is the nature of
undefined behavior.
 
K

Keith Thompson

pai said:
Sorry for not having a clear english dialect.

Context: This was about the "doubt" vs. "question" thing. We've seen
that enough around here that we're (sort of) getting used to it, but
using "question" will make it easier to understand.
I am not able to understand how is the increment works in program 1
and in program 2 why there is a compile error.

here is the code..

---------------------------------------
Program 1
------------------------------------- [snip]
ans = ++i + ++i ; [snip]
ans = ++i + ++i + ++i;

I already answered that in the article to which you're replying.
Once again:


Yes, that's a syntax error. The subexpression "++i" appears twice,
with no operator in between. What were you expecting it to do?

And please read <http://cfaj.freeshell.org/google/> and follow its
advice.
 
L

Lemor

ans = ++i ++i
This gives error while compiling because you did not terminate each of
the ++i statement
with a ';' character.
It should be like this:
ans = ++i;ans = ++i;
OR:
ans=(++i) + (++i);

ans = ++i + +i ;
printf(" %d %d ",ans,i);

here, ans = 1 + 1=2.
because you first increment the value of i by 1 and copy this value in
ans and then u add the current value of i in ans again.
thus, ans=2 and i=1 and so it prints 2 and 1.

i=0;
ans = ++i + ++i ;
printf(" %d %d ",ans,i);

here u initialise i=0, thus no value is there in i.
now you add the twice increment i and add this value in ans.Since ans
had already value of 2 (in the last operation), now its value is 4
since i=2 ans ans=2+2=4;

i=0;
ans = ++i + ++i + ++i;
printf(" %d %d ",ans,i);

Here again you initialise i=0.Now ans is having value 4 already and i
is 3 times incremented and then added to ans. and so ans had the value
4+3=7

and so that is why you get the values 4 and 7 of ans
 
R

Richard Heathfield

Lemor said:
i=0;
ans = ++i + ++i ;
printf(" %d %d ",ans,i);

here u initialise i=0, thus no value is there in i.

Wrong. The value is 0. This /is/ a value. It is not "no value".
now you add the twice increment i and add this value in ans.Since ans
had already value of 2 (in the last operation), now its value is 4
since i=2 ans ans=2+2=4;

No, the behaviour is undefined because:

"Between the previous and next sequence point an object shall have its
stored value modified at most once by the evaluation of an expression.
Furthermore, the prior value shall be accessed only to determine the value
to be stored." - C89, 3.3.
 
K

Kenneth Brody

Fred Kleinschmidt wrote:
[...]
ans = ++i + +i ; [...]
ans = ++i + ++i ; [...]
ans = ++i + ++i + ++i;
[...]
Read the FAQs! This is one of the most common questions.
Basically, you can't auto-increment a variable more than once between
control points. So any statement that increments a variable more than once
leads to undefined behavior.

Actually, you only need to modify it once, as long as you access it more
than once. The following are just as UB as the above, despite the single
modification to "i":

i = i++;
x = i + ++i;

Note that the first example by the OP only modifies "i" once.

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

Dave Thompson

pai wrote:

This is not a legal C comment (nor are C++ style ones, at least for on
compiler).

Of course this is a syntax error. Sequence <expression1> <whitespace>
<expression2> is not legal in C. You have `++i` as both expression 1

It is if expression2 begins with a prefix operator that is also a
binary (infix) operator, namely + - & -- although semantically the
meaning changes from identity to addition, negation to subtraction, or
address to bit-and. Syntactically * would also work but semantically
the (right) operand of prefix-* must be a pointer and infix-* not.
and 2. If you expected something different (and I can't see what that
might have been), keep in mind that compiler follows `maximum munch`
rule, i.e. it reads the code sequentially and tries to make sense of
the longest possible legal sequence of characters. In your case these
are both `++i`s, but stringing them together does not make sense.
The maximal-munch rule applies at the lexical level only. ++i ++i
lexes as ++ i ++ i rather than ++ i + + i or + + i + + i. There is no
single token ++i or ++i++i.

As Keith pointed out elsethread reading the C FAQ at
http://www.c-faq.com/ (maybe even the whole thing, not just 3.2 he
suggested) would help you know the answers to such questions (or even
not to try to ask them of the compiler at all) immediately.
Actually Keith did suggest the whole FAQ as well as (after) 3.2.

- David.Thompson1 at worldnet.att.net
 
D

Dave Thompson

Fred Kleinschmidt wrote:

Actually, you only need to modify it once, as long as you access it more

Actually it's enough to modify once and read once if that read is not
(used) "to [compute] the value to be stored" e.g. x = (i=3) + i;
than once. The following are just as UB as the above, despite the single
modification to "i":

i = i++;

I believe 'modify' in Standardese is interpreted as any store, even of
the existing value, so that one is two stores.
x = i + ++i;

Note that the first example by the OP only modifies "i" once.

- David.Thompson1 at worldnet.att.net
 
J

Jordan Abel

Fred Kleinschmidt wrote:

Actually, you only need to modify it once, as long as you access it more

Actually it's enough to modify once and read once if that read is not
(used) "to [compute] the value to be stored" e.g. x = (i=3) + i;
than once. The following are just as UB as the above, despite the single
modification to "i":

i = i++;

I believe 'modify' in Standardese is interpreted as any store, even of
the existing value, so that one is two stores.

Are you allowed to do two stores of the same value?

i=++i; /* probably not */

but...

f(i=0,i=0) /* is f guaranteed to receive two 0's? is i guaranteed to be
0 afterwards? */

or even
f(i=1,i=3) /* is f guaranteed to receive 1,2? is i guaranteed to be odd?
*/
 
C

Chris Torek

[regarding undefined behavior in expressions that modify objects
multiple times, and so on]

Are you allowed to do two stores of the same value?

No, not technically at least.
i=++i; /* probably not */

This one is definitely out, and could even conceivably misbehave
in some sysetms. (The misbehavior would, I think, depend on the
compiler "knowing" that multiple modifications are not allowed and
therefore assuming that "++i" has not modified "i" because "i=" is
going to modify "i".)
but...

f(i=0,i=0) /* is f guaranteed to receive two 0's? is i guaranteed to be
0 afterwards? */

This is technically illegal, although I find it hard to imagine
any way to cause it to break.
or even
f(i=1,i=3) /* is f guaranteed to receive 1,2? is i guaranteed to be odd?
*/

(Presumably the comment should read "1,3".) This one is also
technically illegal, and one can imagine hardware on which it
behaves badly (multiple simultaneous stores in a VLIW machine, in
which stores are implemented by circuits that are not "wire-OR"
capable, resulting in overheating of the circuits and burning out
parts of the computer[%]).

[% One might object: "But no one would ever build such a machine."
Well, actually, someone *did*. I once programmed a piece of DEC
hardware in which the manual advised taking caution to avoid
programming the bit-slice units to write to the same data lines at
the same time, as they were not wire-OR capable and this could thus
burn out the drive transistors. Curiously, the DEC-supplied driver
-- which was buggy, which is why I was programming the device --
did just what the manual advised against. Perhaps this was why
the device was persistently flaky, although the symptoms did not
match up with the way the hardware must have worked.]
 
D

Dave Thompson

[regarding undefined behavior in expressions that modify objects
multiple times, and so on]
(attribution to Jordan Abel <[email protected]> lost)
but...

f(i=0,i=0) /* is f guaranteed to receive two 0's? is i guaranteed to be
0 afterwards? */

This is technically illegal, although I find it hard to imagine
any way to cause it to break.
Purely as a thought experiment:

On x86 and S/360 and maybe more "sub rega from rega" or "xor" is
(often?) cheaper than "load constant/literal 0 to rega".

I can just barely imagine multiple unsynchronized arith units doing
rega@3 := rega@0 - rega@2
rega@5 := rega@1 - rega@4 # result original value not cleared

- David.Thompson1 at worldnet.att.net
 

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
474,175
Messages
2,570,942
Members
47,490
Latest member
Finplus

Latest Threads

Top