# Thread: could any help me understanding the concepts of increment / decrement operators

1. ## could any help me understanding the concepts of increment / decrement operators

arial black

Does increment and decrement operators acts same in all the cases or they vary in their behaviour . 2. Well they work the 'same', provided you use them in the same context, ie., if you use prefix notation for the increment, the analogous decrement would obviously also be prefix. Likewise for postfix notation.

Code:
```++x or --x /* both prefix */

y++ or y-- /* both postfix */``` 3. >Does increment and decrement operators acts same in all the cases or they vary in their behaviour .
No, the increment operator adds 1 and the decrement operator subtracts 1. Otherwise (provided you match prefix and postfix and the type being acted on isn't at a boundary), they work the same.

There are two variations of increment and decrement. The first is prefix, where the operator goes before the object being acted on. This is where the increment is performed first, then the value of the object is used in an expression:
Code:
```int i = 5;
printf ( "%d\n", ++i ); /* Prints 6 */
printf ( "%d\n", i ); /* Prints 6 */```
The second is postfix, where the operator goes after the object and the value is used in an expression unchanged. Then it is incremented (not really, but that's the behavior, so we can pretend):
Code:
```int i = 5;
printf ( "%d\n", i++ ); /* Prints 5 */
printf ( "%d\n", i ); /* Prints 6 */```
I also mentioned something about a type boundary, and that might be confusing, so let's look at it. Say you have an unsigned int with the value of 0. Matching the prefix and postfix aspect of increment and decrement will not behave the same. From an implementation standpoint, increment will add 1 and decrement will subtract 1, but the resulting values may be surprising if you don't know how unsigned types work:
Code:
```unsigned int i = 0;
printf ( "%d\n", ++i ); /* Prints 1 */```
This works as expected, but this:
Code:
```unsigned int i = 0;
printf ( "%d\n", --i ); /* Prints 32,767 with 2 byte int and 8 bit char */```
Will result in a value that is large because unsigned overflow (and underflow) wrap around. Granted, this is a pedantic distinction on my part, but I'm trying to be symmetrical in my explanation. It's a lead-in to the signed types. If we were using a signed int rather than an unsigned int, the behavior is most definitely different if you're at a boundary:
Code:
```int i = INT_MIN;
printf ( "%d\n", ++i ); /* Prints INT_MIN - 1, -32,766 with our previous size assumption */```
Code:
```int i = INT_MIN;
printf ( "%d\n", --i ); /* Undefined behavior! */```
Signed overflow (and underflow) is undefined, so even if you match prefix increment and decrement on a boundary value, the behavior will still be different.

Of course, for the most part they work in the same manner.  4. Here is a question, is unsigned under/overflow undefined as well then? 5. Originally Posted by Prelude
Code:
```unsigned int i = 0;
printf ("%d\n", ++i ); /* Prints 1 */```
This works as expected, but this:
Code:
```unsigned int i = 0;
printf ( "%d\n", --i ); /* Prints 32,767 with 2 byte int and 8 bit char */```
Will result in a value that is large because unsigned overflow (and underflow) wrap around. Granted, this is a pedantic distinction on my part, but I'm trying to be symmetrical in my explanation. It's a lead-in to the signed types. Of course, for the most part they work in the same manner. Actually, not. This prints -1 in all cases. Your explanantion of ++ and -- is impeccable, but if anyone actually tries this, the results will not be what you have indicated. Internal representations of the numbers are the same. The function printf() doesn't actually know whether a variable is an int or an unsigned int; it just uses the format specifier that you give it.

Try the following:

Code:
```#include <stdio.h>
int main()
{
unsigned int i = 0;
int j = 0;
printf ( "--i = %d, --j = %d\n", --i , --j);
printf("Using %%d: i = %d, j = %d\n", i, j);
printf("Using %%u: i = %u, j = %u\n", i, j);
printf("Using %%x: i = 0x%x, j = 0x%x\n", i, j);

return 0;
}```

If your implementation has 32-bit ints, you will see
--i = -1, --j = -1
Using %d: i = -1, j = -1
Using %u: i = 4294967295, j = 4294967295
Using %x: i = 0xffffffff, j = 0xffffffff
Dave

Oops. Extraneous lines that were originally in this post have been edited out.
[/edit] 6. >the results will not be what you have indicated.
Yes, my mistake. You would think I had learned not to copy and paste sections of my posts to save time. I always end up missing something subtle when I do that. >is unsigned under/overflow undefined as well then?
No, unsigned overflow is well defined. They follow the rules of modulo 2^n arithmetic. Put simply, the values roll over back to the beginning, so there is no overflow. 7. I have also read that a prefixed operator is more efficient than the postfix context, making it a little humorous to think that this is where c++ got it's name. Just something to think about, though I'm sure the difference would be completely irrelevant in anything but time-crucial applications like nuclear missile trackers. 8. >I have also read that a prefixed operator is more efficient than the postfix context
If the context of the expression doesn't require either prefix or postfix, the two are equivalent in behavior and performance. What you're referring to is the fact that postfix must first save a copy of the value and then perform the operation before returning the copied value. This is less efficient in theory from prefix where the copy operation isn't required. Even Dennis Ritchie's first compiler optimized that away to nothing though, and I don't know of any compilers in the last two decades that failed to dole out identical machine code for the two.

It's different in C++ though, where objects can define their own prefix and postfix operators. Postfix is potentially far less efficient than prefix with user defined objects, so the advice that prefix should be favored is sound. Of course, like C, for built-in types the compiler will optimize away any differences. 9. tell me the difference between the following two codes:

1. i=3;
i=++i*++i*++i;
printf("%d",i);

2. i=3,j;
j=++i*++i*++i;
printf("%d",j); 10. Originally Posted by chaitanya
tell me the difference between the following two codes:

1. i=3;
i=++i*++i*++i;
printf("%d",i);

2. i=3,j;
j=++i*++i*++i;
printf("%d",j);
The first expression is not a good idea, and the second one looks fishy too.

You can read about it here and here and probably you should read this too.

~/ 11. Code:
```i=++i*++i*++i;
j=++i*++i*++i;```
The problem is that i is assigned new values in multiple spots in one single expression. This is undefined behaviour. 12. To further the point Magos made: The only difference is that you use an additional variable in the second one. The end result of both of those may be anything. Yes, anything. It is undefined behavior, and as such, you have no control over, nor can you accurately predict what the end result will be in either case.

To finalize that statement: I could make a fully ANSI compatable compiler that would format your hard drive if it came across such expressions, and it still would be ANSI compatable, because according to the standard, what I do to handle that case is up to me, the compiler maker. Thus, I can proudly proclaim my compiler as 100% ANSI compatable, and still have it format your hard drive if you use such an expression. Because what you're doing is undefined, which means anything can happen as a result.

Quzah. Popular pages Recent additions 