Tech Off Thread

33 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

i = 4, i++ + i should return 9, but returns 8

Back to Forum: Tech Off
  • User profile image
    Shining Arcanine

    My C/C++ professor mentioned in class that many compilers cannot properly evaluate the expression i++ + i and some permutations of it, so I decided to test that out in Visual Studio with a small program:

    #include <stdio.h>

    int main ( void )
    {

        int i = 4;

        printf("%i", i++ + i);

        return 0;

    }

    It returns 8. It should return 9. Why does it return 8?

  • User profile image
    TommyCarlier

    Why should it return 9? i++ is evaluated AFTER printf. printf("%i", ++i + i) would return 9.

  • User profile image
    AndyC

    Um, are you sure about that? Surely for i++ + i it should go:

    i++      equates to 4 (then increments i to 5)
    + i       equates to 9

    then printf should display the result of 9.

    For ++i +i it'd be:

    ++i   (increments i to 5) and equates to 5
    +1    equates to 10

    Although I may be wrong, I always did hate pre/postfix incrementing when mixed with other operators.

  • User profile image
    Sven Groot

    AndyC wrote:
    Um, are you sure about that? Surely for i++ + i it should go:

    It should, all things being equal. But thanks to the malarky called sequence points, it isn't the case.

    Basically, about expressions with side effects like i++, C guarantees only that the side effects will be completed at a sequence point (section 1.9, paragraph 7: "At certain specified points in the execution sequence called sequence points, all side effects of previous evaluations shall be complete and no side effects of subsequent evaluations shall have taken place" (that's the C++ standard but I believe the same applies for C).

    The standard specifies where sequence points exist, which includes at the end of a full expression (1.9 paragraph 16) but not inside a subexpression.

    As such the result of the side effect of i++ is only guaranteed to be visible after the full expression i++ + i has been evaluated. Because the standard also doesn't guarantee that the side effects won't be visible yet, the statement above is undefined by the standard and therefore compiler dependent. Some compilers might return 8, othes might return 9. As such, I would strongly recommend against having those kinds of expressions in your program.

  • User profile image
    TommyCarlier

    I wonder what i++ + ++i would evaluate to...

  • User profile image
    stevo_

    Begs the question, how much + would a c ++, if a c + could + c?

  • User profile image
    wkempf

    TommyCarlier wrote:
    I wonder what i++ + ++i would evaluate to...


    Sven already gave you all the information you need to answer that.  It's undefined.  Not to mention evil. Wink

  • User profile image
    Shining Arcanine

    TommyCarlier wrote:
    I wonder what i++ + ++i would evaluate to...


    Going by operator precedence tables, it should be evaluated as follows, assuming i = 4:

    i++ + ++i (i = 4)
    4 + ++i (i = 5)
    4 + 6 (i = 6)
    10 (i = 6)

  • User profile image
    littleguru

    That's why I never liked the ++ and -- operators; confusing.

  • User profile image
    Sven Groot

    But because of the sequence points business, it could also be 9.

  • User profile image
    AndyC

    littleguru wrote:
    That's why I never liked the ++ and -- operators; confusing.


    Me too. I always just introduce temporary variables when expressions start to get complex and work on the principle that the optimizer will most likely make them go away whilst leaving much more readable code.

  • User profile image
    TommyCarlier

    Long live i += 1 !

  • User profile image
    vesuvius

    Why does this work in C# then? Whats going on beneath that's different?

     class Program
        {
            static void Main(string[] args)
            {
                int i = 4;
                Console.Write(i++ + i);
                Console.ReadLine();
            }
        }


    Answer = 9;



  • User profile image
    Sven Groot

    vesuvius wrote:
    Why does this work in C# then?

    Because the C(++) standard has no bearing on the semantics of C#. The C standard defines an abstract machine for the execution of programs, which as I've stated above defines this notion of sequence points which causes the results of this statement to be implementation-defined.

    The C# standard also defines an abstract machine (actually, I think it's the CLI standard that defines the abstract machine that C# runs on) but its semantics can be (and probably are) completely different. I have no idea what guarantees it makes considering statements like this; it might guarantee their correctness or it might leave it to the implementation like C does. In the latter case, the fact that Microsoft's compiler does it correctly would be coincidence and not something you can rely on to be true in other compilers (e.g. Mono). But if the standard does define it (I don't know if it does, I haven't read the C# and CLI standards as closely as the C++ standard) you can depend on it.

    Bottom line: in C (and C++) the result of these expressions is implementation-defined. But that means nothing for other languages.

    It's also nonsense like this that made the VB team decide to keep these unary operators out of VB, even though they did introduce the += style operators in VB2005.

  • User profile image
    tgraupmann

    Just use:

    [code]

    i += i + 1;

    [/code]

  • User profile image
    Sven Groot

    tgraupmann wrote:
    Just use:

    [code]

    i += i + 1;

    [/code]

    That does something completely different from the original code.

  • User profile image
    Shining Arcanine

    Sven Groot wrote:
    But because of the sequence points business, it could also be 9.


    It probably is 9 in Visual Studio, but it should be 10.

  • User profile image
    Sven Groot

    Shining Arcanine wrote:
    
    Sven Groot wrote:
    But because of the sequence points business, it could also be 9.


    It probably is 9 in Visual Studio, but it should be 10.

    No, I checked it, it's 10. I guess the ++i causes it to re-read i for the second access (which is sort of required in this case to ensure the correct final value of i).

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.