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

  1. #1
    Registered User
    Join Date
    Aug 2004
    Posts
    8

    Question 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. #2
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    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. #3
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >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.
    My best code is written with the delete key.

  4. #4
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Here is a question, is unsigned under/overflow undefined as well then?

  5. #5
    Registered User
    Join Date
    Mar 2004
    Posts
    536
    Quote 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

    [edit]
    Oops. Extraneous lines that were originally in this post have been edited out.
    [/edit]
    Last edited by Dave Evans; 08-29-2004 at 09:30 AM.

  6. #6
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >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.
    My best code is written with the delete key.

  7. #7
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    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. #8
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >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.
    My best code is written with the delete key.

  9. #9
    Registered User
    Join Date
    Aug 2004
    Posts
    8
    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. #10
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Quote 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.

    ~/
    Last edited by kermit; 08-30-2004 at 03:57 AM.

  11. #11
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    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.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  12. #12
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    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.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How Does Increment Operators Work...??
    By ajayd in forum C Programming
    Replies: 37
    Last Post: 12-31-2008, 10:01 AM
  2. Bolean Operators hurt my head. (Trouble understanding) :(
    By Funcoot in forum C++ Programming
    Replies: 3
    Last Post: 01-20-2008, 07:42 PM
  3. Increment / Decrement Operators - Help
    By shyam168 in forum C Programming
    Replies: 6
    Last Post: 03-29-2006, 09:24 PM
  4. confusion with increment and decrement operators
    By cBegginer in forum C Programming
    Replies: 6
    Last Post: 03-19-2005, 03:45 PM
  5. increment and decrement operators
    By ee0u22ba in forum C++ Programming
    Replies: 5
    Last Post: 10-18-2003, 04:57 AM