i++ * i++

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • rohit

    i++ * i++

    #include <stdio.h>
    #define PRODUCT(x) (x*x)

    int main()
    {

    int i =3,j,k;
    j = PRODUCT(i++);
    k = PRODUCT(++i);

    printf("\n%d %d", j,k);

    return (0);
    }

    -----------------------------------------------------------
    The output is 9 and 49

    shouldn't the answer be 12 and 20?

    What are the steps the compiler takes to reach the above given output?

  • Thomas Lumley

    #2
    Re: i++ * i++


    rohit wrote:[color=blue]
    > #include <stdio.h>
    > #define PRODUCT(x) (x*x)[/color]

    This is asking for trouble: consider PRODUCT(2+2), which expands to
    2+2*2+2,
    ie 8 rather than 16, but that isn't what is causing this particular
    problem.
    [color=blue]
    > int main()
    > {
    >
    > int i =3,j,k;
    > j = PRODUCT(i++);[/color]

    This is undefined behaviour: it expands to i++*i++
    [color=blue]
    > k = PRODUCT(++i);
    >
    > printf("\n%d %d", j,k);
    >
    > return (0);
    > }
    >
    > -----------------------------------------------------------
    > The output is 9 and 49[/color]

    Ok.
    [color=blue]
    > shouldn't the answer be 12 and 20?[/color]

    No. It can be anything. Yes, anything.
    [color=blue]
    > What are the steps the compiler takes to reach the above given output?[/color]

    Whatever it feels like.

    Read the FAQ (starting with question 3.2, which is exactly this
    question). (c-faq.com)
    You might also find
    http://www.eskimo.com/~scs/readings/undef.981105.html useful.

    There is actually a perfectly sensible explanation for how the program
    might have computed 9 and 49, but trying to second-guess undefined
    behaviour is a bad idea.

    -thomas

    Comment

    • Chris Smith

      #3
      Re: i++ * i++

      rohit <rohit1712@gmai l.com> wrote:[color=blue]
      > #include <stdio.h>
      > #define PRODUCT(x) (x*x)
      >
      > int main()
      > {
      >
      > int i =3,j,k;
      > j = PRODUCT(i++);
      > k = PRODUCT(++i);
      >
      > printf("\n%d %d", j,k);
      >
      > return (0);
      > }
      >
      > -----------------------------------------------------------
      > The output is 9 and 49[/color]

      For your compiler on your hardware platform, anyway.
      [color=blue]
      > shouldn't the answer be 12 and 20?[/color]

      The answer is that multiple assignments between sequence points yield
      undefined behavior.

      --

      The Easiest Way To Train Anyone... Anywhere.

      Chris Smith - Lead Software Developer/Technical Trainer
      MindIQ Corporation

      Comment

      • Grumble

        #4
        Re: i++ * i++

        rohit wrote:[color=blue]
        > #include <stdio.h>
        > #define PRODUCT(x) (x*x)
        >
        > int main()
        > {
        > int i =3,j,k;
        > j = PRODUCT(i++);
        > k = PRODUCT(++i);
        >
        > printf("\n%d %d", j,k);
        >
        > return (0);
        > }
        >
        > The output is 9 and 49
        >
        > shouldn't the answer be 12 and 20?[/color]

        You'll want to read http://c-faq.com/expr/

        Comment

        • Steve

          #5
          Re: i++ * i++

          When the compiler sees the i++ the value of i is not actually ever
          incremented until after the current statement has executed. So when you
          say i++ when i = 3 in that statement it is always 3 in that statement.
          You increment the value twice since it says i++ * i++ only in the next
          statement. With the ++i the value is incremented before the statement
          starts so it sees a 5 from the above line then increments twice to 7 and
          then preforms the PRODUCT.

          rohit wrote:[color=blue]
          > #include <stdio.h>
          > #define PRODUCT(x) (x*x)
          >
          > int main()
          > {
          >
          > int i =3,j,k;
          > j = PRODUCT(i++);
          > k = PRODUCT(++i);
          >
          > printf("\n%d %d", j,k);
          >
          > return (0);
          > }
          >
          > -----------------------------------------------------------
          > The output is 9 and 49
          >
          > shouldn't the answer be 12 and 20?
          >
          > What are the steps the compiler takes to reach the above given output?
          >[/color]

          Comment

          • Lew Pitcher

            #6
            Re: i++ * i++

            -----BEGIN PGP SIGNED MESSAGE-----
            Hash: SHA1

            rohit wrote:[color=blue]
            > #include <stdio.h>
            > #define PRODUCT(x) (x*x)
            >
            > int main()
            > {
            >
            > int i =3,j,k;
            > j = PRODUCT(i++);
            > k = PRODUCT(++i);
            >
            > printf("\n%d %d", j,k);
            >
            > return (0);
            > }
            >
            > -----------------------------------------------------------
            > The output is 9 and 49
            >
            > shouldn't the answer be 12 and 20?[/color]

            Nope. Because your code modifies an object twice between sequence
            points, you've strayed into the realm of "undefined behaviour", and
            /any/ answer is the "proper" answer.
            [color=blue]
            > What are the steps the compiler takes to reach the above given output?[/color]

            1) Flip Magic 8 Ball back and forth three times
            2) Turn Magic 8 Ball face down
            3) Read answer from Magic 8 Ball window

            or not



            - --

            Lew Pitcher, IT Specialist, Corporate Technology Solutions,
            Enterprise Technology Solutions, TD Bank Financial Group

            (Opinions expressed here are my own, not my employer's)
            -----BEGIN PGP SIGNATURE-----
            Version: GnuPG v1.4.2.2 (MingW32)
            Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

            iD8DBQFEGYuBagV FX4UWr64RAgNlAK DZqIXvfF7lVMFMr R2VP4m68URgPQCg z7aN
            dLkdF+Tl22Pt4hX N3e0yIyw=
            =NM3n
            -----END PGP SIGNATURE-----

            Comment

            • Ben C

              #7
              Re: i++ * i++

              On 2006-03-16, rohit <rohit1712@gmai l.com> wrote:[color=blue]
              > #include <stdio.h>
              > #define PRODUCT(x) (x*x)
              >
              > int main()
              > {
              >
              > int i =3,j,k;
              > j = PRODUCT(i++);
              > k = PRODUCT(++i);
              >
              > printf("\n%d %d", j,k);
              >
              > return (0);
              > }
              >
              > -----------------------------------------------------------
              > The output is 9 and 49
              >
              > shouldn't the answer be 12 and 20?
              >
              > What are the steps the compiler takes to reach the above given output?
              >[/color]

              See the FAQ, 3.1


              Comment

              • Richard Bos

                #8
                Re: i++ * i++

                Steve <gtg257u@mail.g atech.edu> wrote:

                [ Do not top-post, please. ]
                [color=blue][color=green]
                > > #define PRODUCT(x) (x*x)[/color][/color]
                [color=blue][color=green]
                > > j = PRODUCT(i++);
                > > k = PRODUCT(++i);[/color][/color]
                [color=blue][color=green]
                > > The output is 9 and 49
                > >
                > > shouldn't the answer be 12 and 20?[/color][/color]
                [color=blue]
                > When the compiler sees the i++ the value of i is not actually ever
                > incremented until after the current statement has executed.[/color]

                This is wrong. What happens when you execute i++ is this:
                - the value returned is the value of i before this expression, _and_
                - i is incremented.
                In which order these are done is not defined; they could even be done in
                parallel.
                [color=blue]
                > So when you
                > say i++ when i = 3 in that statement it is always 3 in that statement.[/color]

                This, too, is wrong.

                Richard

                Comment

                • Chris Dollin

                  #9
                  Re: i++ * i++

                  rohit wrote:
                  [color=blue]
                  > #include <stdio.h>
                  > #define PRODUCT(x) (x*x)[/color]

                  Should be ((x)*(x)) - consider the argument `i + 1`.

                  Actually, more like "should be `int product(x) { return x*x; }`.
                  [color=blue]
                  > int main()
                  > {
                  >
                  > int i =3,j,k;
                  > j = PRODUCT(i++);[/color]

                  BOOM.
                  [color=blue]
                  > k = PRODUCT(++i);
                  >
                  > printf("\n%d %d", j,k);
                  >
                  > return (0);
                  > }
                  >
                  > -----------------------------------------------------------
                  > The output is 9 and 49
                  >
                  > shouldn't the answer be 12 and 20?[/color]

                  This a FAQ, so see the C FAQ, eg


                  question 3.2
                  [color=blue]
                  > What are the steps the compiler takes to reach the above given output?[/color]

                  It compiles code for `i++ * i++` assuming that you know what you're
                  doing. So, at a guess, it multiples i (3) by i (still 3) to get 9.
                  The it increments i, possibly twice.

                  The it compiles code for `++i * ++i` ATYKWYD. At a guess, it increments
                  i, probably twice, then multiplies i (7) by i (still 7) to get 49.

                  The compiler-writer of course could do things differently. They could
                  keep a flag for each variable, "increment pending". Then `i++` compiles
                  as "get the value of i and set the flag", and ";" compiles as "increment
                  all variables with the flag set, and clear it"; and "++i" compiles as
                  "increment i, and return the new value". In that case, you'd
                  get the results 9 and 20.

                  Or they could compile `i++` as "if the flag is set, report a problem,
                  plant code to quit the program; otherwise, get the value of i and
                  set the flag."

                  --
                  Chris "sparqling" Dollin
                  "Who do you serve, and who do you trust?"

                  Comment

                  • Steve

                    #10
                    Re: i++ * i++

                    This is short sighted because of a few other reasons but wrong is
                    extremely, just another way to interpret the actions the final result.
                    Thanks though for pointing it out.

                    Richard Bos wrote:[color=blue]
                    > Steve <gtg257u@mail.g atech.edu> wrote:
                    >
                    > [ Do not top-post, please. ]
                    >[color=green][color=darkred]
                    >>> #define PRODUCT(x) (x*x)[/color][/color]
                    >[color=green][color=darkred]
                    >>> j = PRODUCT(i++);
                    >>> k = PRODUCT(++i);[/color][/color]
                    >[color=green][color=darkred]
                    >>> The output is 9 and 49
                    >>>
                    >>> shouldn't the answer be 12 and 20?[/color][/color]
                    >[color=green]
                    >> When the compiler sees the i++ the value of i is not actually ever
                    >> incremented until after the current statement has executed.[/color]
                    >
                    > This is wrong. What happens when you execute i++ is this:
                    > - the value returned is the value of i before this expression, _and_
                    > - i is incremented.
                    > In which order these are done is not defined; they could even be done in
                    > parallel.
                    >[color=green]
                    >> So when you
                    >> say i++ when i = 3 in that statement it is always 3 in that statement.[/color]
                    >
                    > This, too, is wrong.
                    >
                    > Richard[/color]

                    Comment

                    • Kenneth Brody

                      #11
                      Re: i++ * i++

                      Steve wrote:

                      [Again, please don't top post. Top-posting corrected for this reply.]
                      [color=blue]
                      > Richard Bos wrote:[color=green]
                      > > Steve <gtg257u@mail.g atech.edu> wrote:
                      > >
                      > > [ Do not top-post, please. ]
                      > >[color=darkred]
                      > >>> #define PRODUCT(x) (x*x)[/color]
                      > >[color=darkred]
                      > >>> j = PRODUCT(i++);
                      > >>> k = PRODUCT(++i);[/color]
                      > >[color=darkred]
                      > >>> The output is 9 and 49
                      > >>>
                      > >>> shouldn't the answer be 12 and 20?[/color]
                      > >[color=darkred]
                      > >> When the compiler sees the i++ the value of i is not actually ever
                      > >> incremented until after the current statement has executed.[/color]
                      > >
                      > > This is wrong. What happens when you execute i++ is this:
                      > > - the value returned is the value of i before this expression, _and_
                      > > - i is incremented.
                      > > In which order these are done is not defined; they could even be done in
                      > > parallel.
                      > >[color=darkred]
                      > >> So when you
                      > >> say i++ when i = 3 in that statement it is always 3 in that statement.[/color]
                      > >[/color]
                      > This is short sighted because of a few other reasons but wrong is
                      > extremely, just another way to interpret the actions the final result.
                      > Thanks though for pointing it out.[/color]

                      No, your answer was wrong. Had you said "it appears that your particular
                      compiler, given the command line flags you specified, has generated code
                      which behaves as ...", you might have been "right". But your generalized
                      statement implying that "the meaning of post- and pre-increment is..." is
                      simply untrue.

                      --
                      +-------------------------+--------------------+-----------------------------+
                      | Kenneth J. Brody | www.hvcomputer.com | |
                      | kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer .h> |
                      +-------------------------+--------------------+-----------------------------+
                      Don't e-mail me at: <mailto:ThisIsA SpamTrap@gmail. com>

                      Comment

                      • arnold

                        #12
                        Re: i++ * i++

                        Richard Bos wrote:
                        [color=blue]
                        > This is wrong. What happens when you execute i++ is this:
                        > - the value returned is the value of i before this expression, _and_
                        > - i is incremented.
                        > In which order these are done is not defined; they could even be done in
                        > parallel.[/color]

                        Could you explain? When you say "order is not defined" are you talking
                        about these two?
                        [color=blue][color=green][color=darkred]
                        >>> j = PRODUCT(i++);
                        >>> k = PRODUCT(++i);[/color][/color][/color]

                        I allways thought that a statement like i++ meant

                        first use the value of i then increment it

                        since this is a macro does it change how it works or did i fundamentally
                        misunderstand.

                        arnold

                        Comment

                        • Artie Gold

                          #13
                          Re: i++ * i++

                          arnold wrote:[color=blue]
                          > Richard Bos wrote:
                          >[color=green]
                          >> This is wrong. What happens when you execute i++ is this:
                          >> - the value returned is the value of i before this expression, _and_
                          >> - i is incremented.
                          >> In which order these are done is not defined; they could even be done in
                          >> parallel.[/color]
                          >
                          >
                          > Could you explain? When you say "order is not defined" are you talking
                          > about these two?
                          >[/color]
                          [some context restored]
                          [color=blue][color=green][color=darkred]
                          > >>> #define PRODUCT(x) (x*x)
                          > >>> j = PRODUCT(i++);
                          > >>> k = PRODUCT(++i);[/color][/color]
                          >
                          > I allways thought that a statement like i++ meant
                          >
                          > first use the value of i then increment it
                          >
                          > since this is a macro does it change how it works or did i fundamentally
                          > misunderstand.
                          >[/color]
                          Well, it's not the individual applications of ++ (whether prefix or
                          postfix) that are a problem, it's the fact that multiple side effects
                          occur without an intervening sequence point.

                          Consider the expansions of the expressions above:

                          PRODUCT(i++) => i++ * i++ and
                          PRODUCT(++i) => ++i * ++i

                          in both cases the variable `i' is side affected (did I really say `side
                          affected'?) twice with no intervening sequence point; since the order in
                          which things occur is specifically undefined, the overall behavior is
                          undefined as well.

                          The C standard, *could*, of course, have defined the order. But it
                          doesn't. [And that's not likely to change.]

                          HTH,
                          --ag


                          --
                          Artie Gold -- Austin, Texas
                          I will (ir)regularly write about things that are important to me -- that I hope interest you. Of course, since I see most things as being political, that will be most of it.

                          "You can't KISS* unless you MISS**"
                          [*-Keep it simple, stupid. **-Make it simple, stupid.]

                          Comment

                          • Chris Smith

                            #14
                            Re: i++ * i++

                            arnold <arnold@example .net> wrote:[color=blue]
                            > I allways thought that a statement like i++ meant
                            >
                            > first use the value of i then increment it[/color]

                            No, that's not it. It means "increment i" and also "the result of the
                            expression is the value that i had before being incremented". This
                            implies nothing at all about the order in which the increment or the use
                            of the value of the expression occur. It's entirely possible that the
                            compiler will generate code to store off the value of i, increment i
                            immediately, and then use that temporary value in another expression.
                            Or alternatively, generate code to increment i first, then make a copy
                            and subtract one from the copy. Or, alternatively, generate a machine
                            code instruction that performs the increment simultaneously with using
                            the original value in another expression.

                            More importantly, your macro expands to increment i twice, not just
                            once. The variable i is therefore modified twice, in an undefined order
                            and perhaps even in parallel, and the result is therefore completely
                            undefined.
                            [color=blue]
                            > since this is a macro does it change how it works or did i fundamentally
                            > misunderstand.[/color]

                            The macro just expanded PRODUCT(i++) to "i++ * i++", which I assume you
                            knew, since you wrote the expanded form in the subject line. It's the
                            multiple modifications to i between sequence points that yield the
                            undefined behavior.

                            --

                            The Easiest Way To Train Anyone... Anywhere.

                            Chris Smith - Lead Software Developer/Technical Trainer
                            MindIQ Corporation

                            Comment

                            • arnold

                              #15
                              Re: i++ * i++


                              Chris Smith wrote:
                              [color=blue]
                              > The macro just expanded PRODUCT(i++) to "i++ * i++", which I assume you
                              > knew, since you wrote the expanded form in the subject line. It's the
                              > multiple modifications to i between sequence points that yield the
                              > undefined behavior.[/color]

                              Chris, it wasn't me, it was this other guy called rohit, the OP:)

                              [color=blue]
                              > More importantly, your macro expands to increment i twice, not just
                              > once. The variable i is therefore modified twice, in an undefined order
                              > and perhaps even in parallel, and the result is therefore completely
                              > undefined.[/color]

                              The reason i++ is used twice is because its a macro? dont know much
                              about macros:( meaning the argument is literally copied into the
                              expression of the macro hence being duplicated?

                              So if it had been a function, it would be given the value i and then, in
                              the next call, i+2. That would have given the values 9 and 25, and there
                              would be no undefined behaviour. correct or mistaken again?
                              [color=blue]
                              > arnold <arnold@example .net> wrote:
                              >[color=green]
                              >>I allways thought that a statement like i++ meant
                              >>
                              >> first use the value of i then increment it[/color]
                              >
                              >
                              > No, that's not it. It means "increment i" and also "the result of the
                              > expression is the value that i had before being incremented". This
                              > implies nothing at all about the order in which the increment or the use
                              > of the value of the expression occur. It's entirely possible that the
                              > compiler will generate code to store off the value of i, increment i
                              > immediately, and then use that temporary value in another expression.
                              > Or alternatively, generate code to increment i first, then make a copy
                              > and subtract one from the copy. Or, alternatively, generate a machine
                              > code instruction that performs the increment simultaneously with using
                              > the original value in another expression.[/color]

                              ok, see. so logically, within one expression, that would mean

                              use value of i, in the next expression containing i use i+1

                              let me check if I understand, an expression of the form

                              (((i_1++ - b) / 3) + i_2++) + c-i_3)

                              would then mean

                              i_1 expression: use value of i_1,
                              i_2 expression: use value of i_1+1,
                              i_3 expression: use value of i_1+2


                              But since the OP's expression uses macro it al changes and leads to
                              undefined behaviour.

                              If this is correct the I think I understand,

                              arnold

                              Comment

                              Working...