Thread: i=i++

  1. #1
    pwning noobs Zlatko's Avatar
    Join Date
    Jun 2009
    Location
    The Great White North
    Posts
    132

    i=i++

    I came across the code i=i++ today. It does increment i, but it surprised me. If post-increment is supposed to return the old value, why is the old value not assigned back to i ? I expected the line to have no effect on i.

  2. #2
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    If I recall correctly, this is undefined behaviour. It will do different things on different machines, and might do different things if you run your program while eating cheese on a wednesday as opposed to a thursday.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    You go to the doughnut shop. The clerk tells you "We have a special today - if you can ID yourself correctly, we'll give you a free donut." You show your ID.

    Then the clerk gives you a free donut.

    I believe that i would always be incremented. Any day of the week, regardless of the food you eat. The i=i bit is logical nonsense, since obviously i is equal to itself.

  4. #4
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    It is indeed undefined. You're not allowed to modify an object multiple times without what's called a “sequence point” in between. See Annex C in C99 for a (hopefully complete) list of sequence points in C.

    Technically anything can happen, but in reality, a value (maybe not the one you expect) will likely get assigned to “i”. What value depends on how your compiler handles this line. For example, it's perfectly legal for a compiler to do the following:
    • Load the value of i somewhere
    • Execute the increment
    • Store the (previously-loaded) value of i into i

    Equivalent code:
    Code:
    int tmp = i++;
    i = tmp;
    Voilà: i’s value does not change. Of course, the compiler could also:
    • Load the value of i somewhere
    • Store the (previously-loaded) value of i into i
    • Execute the increment

    Equivalent code:
    Code:
    i = i;
    i++;
    Now you do get an increment. The moral of the story: don't do that!

    For the record, on my system, i is incremented on the following compilers:
    • gcc 4.5.1
    • Intel
    • Solaris Studio (previously Sun Studio)

    It is not incremented with:
    • gcc 3.4.6
    • TinyCC
    • pcc
    • clang
    • Open64
    • cparser

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Since i = i can't BE a modification, you aren't modifying i more than once, between sequence points.

    Turbo C gets this right. The post increment should happen AFTER any other processing before the sequence point is reached.

    So how could a standard compliant compiler NOT increment i ?

    Compilers that fail this, are brain dead.

  6. #6
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Since i = i can't BE a modification, you aren't modifying i more than once, between sequence points.
    You misunderstood. The "equivalent code" sections are not supposed to be undefined. They explain, in (defined) C terms, how a compiler might implement i = i++.
    Turbo C gets this right. The post increment should happen AFTER any other processing before the sequence point is reached.

    So how could a standard compliant compiler NOT increment i ?
    If you're talking about "i = i; i++" then yes, as I mentioned, that's where the increment happens. If you're talking about "i = i++", then compilers can do what they want because the standard says that's undefined. You can argue that the standard is brain dead, if you'd like, but not compilers: they're following the spec.

  7. #7
    Registered User
    Join Date
    Oct 2008
    Posts
    1,262
    Quote Originally Posted by cas View Post
    You can argue that the standard is brain dead, if you'd like, but not compilers: they're following the spec.
    Seconded, though I expect there is a very good reason for this in the standard: optimization. Disallowing such a thing, I think, makes optimization easier, better and safer for compilers.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Adak
    Since i = i can't BE a modification, you aren't modifying i more than once, between sequence points.
    If you prefer, you could see the equivalent code for v = i++; as:
    Code:
    {
        int t = i;
        i++;
        v = t;
    }
    Hence the equivalent code for i = i++; would be:
    Code:
    {
        int t = i;
        i++;
        i = t;
    }
    Quote Originally Posted by Adak
    The post increment should happen AFTER any other processing before the sequence point is reached.
    Consider:
    Code:
    int i = 0, j = 0;
    int k = i++ + j++;
    Assuming that operations are not somehow performed in parallel, Turbo C cannot implement the post increment for either i or j "AFTER any other processing before the sequence point is reached", because the post increment for one must come before the other. But, it can implement it such that both post increments appear to be "AFTER any other processing before the sequence point is reached".

    Now, consider the above equivalent code for v = i++;. The net effect is equivalent to:
    Code:
    {
        int t = i;
        v = t;
        i++;
    }
    So, my v = i++; equivalent code does implement it such that the post increment appears to be "AFTER any other processing before the sequence point is reached".

    Quote Originally Posted by Adak
    So how could a standard compliant compiler NOT increment i ?
    As shown, even if the compiler was not going out of its way to take advantage of the undefined behaviour clause to do something funny, it could well be that by applying its usual procedure, a result is obtained such that the increment is indeed implemented, but the net effect is that the variable's value is not incremented.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    K&R page 105 has a pointer version of strcpy() as this little beauty:
    Code:
    void strcpy(char *s, char *t) {
       while((*s++ = *t++) != '\0')
       ;
    }
    Which seems VERY similar to our topical bit of code:
    Code:
    i=i++;
    Despite all other logical machinations, it has an increment to i in it.

    If I couldn't trust a compiler to do the latter code correctly, I wouldn't trust it to do the former.

  10. #10
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    Quote Originally Posted by Adak View Post
    K&R page 105 has a pointer version of strcpy() as this little beauty:
    Code:
    void strcpy(char *s, char *t) {
       while((*s++ = *t++) != '\0')
       ;
    }
    Which seems VERY similar to our topical bit of code:
    Code:
    i=i++;
    The former does not modify an object twice in between sequence points. The latter does. It's just that simple.
    Despite all other logical machinations, it has an increment to i in it.

    If I couldn't trust a compiler to do the latter code correctly, I wouldn't trust it to do the former.
    Anything a compiler does for i=i++ is correct. It sounds like you're interested in a language that might be called "Adak C"; and indeed, compilers seem to get i=i++ wrong in that language, but they don't get it wrong in C.

  11. #11
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    The former only modifies each variable once - and is well defined.
    The latter modifies i TWICE, and is thus undefined garbage.

    Whatever you image your compiler as "doing what I expect" as being a proof of correctness, you can be sure that you are flat out wrong.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  12. #12
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    @Salem: No such image of how a compiler works. Just an opinion of it's performance.

    @cas: Absolutely right! I would make some changes in C, if able.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Adak
    Absolutely right! I would make some changes in C, if able.
    Yeah, like make i = i++; result in a compile error. Oh wait, that is actually already allowed in C, but existing compilers do not do more than warn (but you can treat warnings as errors, if you wish), if they do warn at all.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,666
    Your very question in the c.l.c FAQ
    Question 3.3

    If you want to go and argue your case with them, then feel free. But you´re just gonna get your ass handed to you on a plate.

    Sooner or later, your multiple side effects will bite you.
    Salem´s undefined expression sampler

    How many compilers have YOU surveyed to come up with your "cast iron proof of correctness"?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed