why is it so ?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • junky_fellow@yahoo.co.in

    #1

    why is it so ?

    Why

    i = ++i; is undefined
    but
    i = func(++i); is defined ?

    I know there is a sequence point after a call to a function
    after the arguments have been evaluated. But I am not able
    to visualise how the sequence point makes the second statement
    defined ? Also can someone give me a detailed explanation of
    why first statement is undefined ?

    Thanx for any help in advance...

  • Robert Gamble

    #2
    Re: why is it so ?

    junky_fellow@ya hoo.co.in wrote:[color=blue]
    > Why
    >
    > i = ++i; is undefined
    > but
    > i = func(++i); is defined ?
    >
    > I know there is a sequence point after a call to a function
    > after the arguments have been evaluated. But I am not able
    > to visualise how the sequence point makes the second statement
    > defined ?[/color]

    See the recent thread entitled "Sequence points and function calls" on
    comp.std.c.
    [color=blue]
    > Also can someone give me a detailed explanation of
    > why first statement is undefined?[/color]

    The standard states that an object shall not have its stored value
    modified more than once between sequence points, your example modifies
    i twice without an intervening SP, its pretty straight-forward I think.
    If you still don't understand you'll have to be more specific about
    what are having trouble grasping.

    Robert Gamble

    Comment

    • junky_fellow@yahoo.co.in

      #3
      Re: why is it so ?



      Robert Gamble wrote:
      <snip>[color=blue]
      >[color=green]
      > > Also can someone give me a detailed explanation of
      > > why first statement is undefined?[/color]
      >
      > The standard states that an object shall not have its stored value
      > modified more than once between sequence points, your example modifies
      > i twice without an intervening SP, its pretty straight-forward I think.
      > If you still don't understand you'll have to be more specific about
      > what are having trouble grasping.
      >
      > Robert Gamble[/color]

      Still I don't understand what's the harm in doing that. Can
      you please show (step by step) how this will lead to different results
      on different complilers ?

      Comment

      • Robert Gamble

        #4
        Re: why is it so ?

        junky_fellow@ya hoo.co.in wrote:[color=blue]
        > Robert Gamble wrote:
        > <snip>[color=green]
        > >[color=darkred]
        > > > Also can someone give me a detailed explanation of
        > > > why first statement is undefined?[/color]
        > >
        > > The standard states that an object shall not have its stored value
        > > modified more than once between sequence points, your example modifies
        > > i twice without an intervening SP, its pretty straight-forward I think.
        > > If you still don't understand you'll have to be more specific about
        > > what are having trouble grasping.
        > >
        > > Robert Gamble[/color]
        >
        > Still I don't understand what's the harm in doing that.[/color]

        The harm? It invokes undefined behavior.
        [color=blue]
        > Can you please show (step by step) how this will lead to different results
        > on different complilers ?[/color]

        Outside of the aforementioned restriction placed by the Standard, there
        is only one logical way to evaluate the expression i=++i, the same way
        that i=++j would be evaluated, with the value of i being increased by
        one in the former example. But the Standard does place the restriction
        there and since i is modified twice (once for the increment operator
        and once for the assignment operator) the behavior is undefined. I
        don't know exact the reasoning behind the restriction with regards to
        non-ambiguous expressions but suspect it has to do with the complexity
        involved with trying to come up with wording to define what is
        ambiguous and what is not.

        Robert Gamble

        Comment

        • Chris Torek

          #5
          Re: why is it so ?

          In article <1121792861.235 914.122600@z14g 2000cwz.googleg roups.com>
          Robert Gamble <rgamble99@gmai l.com> wrote:[color=blue]
          >Outside of the aforementioned restriction placed by the Standard, there
          >is only one logical way to evaluate the expression i=++i ...[/color]

          Which "one way" is that? Is that the one that goes:

          "increment variable i as stored in register %l2, then
          register %l2 to register %l2"

          or would perhaps be:

          "remember to increment register %l2; then compute %l2+1
          with result going into %l2; then execute remembered increment,
          so increment register %l2"

          ? Note that the latter winds up with "i" increasing by two
          instead of 1, but both emit two instructions:

          inc %l2
          mov %l2,%l2

          or:

          add %l2,1,%l2
          inc %l2

          and "add" and "mov" are both single-cycle instructions ("mov" is
          an assembler alias for "logical-or with register %g0").
          --
          In-Real-Life: Chris Torek, Wind River Systems
          Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
          email: forget about it http://web.torek.net/torek/index.html
          Reading email is like searching for food in the garbage, thanks to spammers.

          Comment

          • Keith Thompson

            #6
            Re: why is it so ?

            junky_fellow@ya hoo.co.in writes:[color=blue]
            > Robert Gamble wrote:
            > <snip>[color=green]
            >>[color=darkred]
            >> > Also can someone give me a detailed explanation of
            >> > why first statement is undefined?[/color]
            >>
            >> The standard states that an object shall not have its stored value
            >> modified more than once between sequence points, your example modifies
            >> i twice without an intervening SP, its pretty straight-forward I think.
            >> If you still don't understand you'll have to be more specific about
            >> what are having trouble grasping.
            >>
            >> Robert Gamble[/color]
            >
            > Still I don't understand what's the harm in doing that. Can
            > you please show (step by step) how this will lead to different results
            > on different complilers ?[/color]

            The statement in question was

            i = i++;

            It exhibits undefined behavior because the standard says it invokes
            undefined behavior.

            Optimizing compilers can perform various transformations on your code;
            the generated assembly or machine code may bear little obvious
            resemblance to what you wrote, except that it behaves the same way.
            Since undefined behavior can do anything, the optimizer is allowed to
            assume that there is no undefined behavior. If this assumption turns
            out to be incorrect, the results can be arbitrarily bad -- and it's
            your fault, not the optimizer's. "If you lie to the compiler, it will
            get its revenge." -- Henry Spencer

            And in this particular case, nothing would be gained by defining the
            behavior. There is no reason to write
            i = i++;
            in the first place. If you want to increment i, just write
            i++;
            Assigning the result back to i would be superfluous even if it worked.

            --
            Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
            San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
            We must do something. This is something. Therefore, we must do this.

            Comment

            • Robert Gamble

              #7
              Re: why is it so ?

              Chris Torek wrote:[color=blue]
              > In article <1121792861.235 914.122600@z14g 2000cwz.googleg roups.com>
              > Robert Gamble <rgamble99@gmai l.com> wrote:[color=green]
              > >Outside of the aforementioned restriction placed by the Standard, there
              > >is only one logical way to evaluate the expression i=++i ...[/color]
              >
              > Which "one way" is that? Is that the one that goes:
              >
              > "increment variable i as stored in register %l2, then
              > register %l2 to register %l2"[/color]

              This makes sense (assuming a non-optimizing compiler)
              [color=blue]
              > or would perhaps be:
              >
              > "remember to increment register %l2; then compute %l2+1
              > with result going into %l2; then execute remembered increment,
              > so increment register %l2"[/color]

              This might make sense if the expression was i = i++ but I don't think
              this would be a valid way to handle i = ++i.

              Robert Gamble

              Comment

              • Flash Gordon

                #8
                Re: why is it so ?

                Robert Gamble wrote:[color=blue]
                > Chris Torek wrote:
                >[color=green]
                >>In article <1121792861.235 914.122600@z14g 2000cwz.googleg roups.com>
                >>Robert Gamble <rgamble99@gmai l.com> wrote:
                >>[color=darkred]
                >>>Outside of the aforementioned restriction placed by the Standard, there
                >>>is only one logical way to evaluate the expression i=++i ...[/color]
                >>
                >>Which "one way" is that? Is that the one that goes:
                >>
                >> "increment variable i as stored in register %l2, then
                >> register %l2 to register %l2"[/color]
                >
                > This makes sense (assuming a non-optimizing compiler)
                >
                >[color=green]
                >>or would perhaps be:
                >>
                >> "remember to increment register %l2; then compute %l2+1
                >> with result going into %l2; then execute remembered increment,
                >> so increment register %l2"[/color]
                >
                >
                > This might make sense if the expression was i = i++ but I don't think
                > this would be a valid way to handle i = ++i.[/color]

                Well, here is a way it could do it on a processor that can run
                instructions in parallel:
                t = i + 1
                In parallel write t to i and increment i
                SIGINSTRUCTIONC LASH
                i.e. bang because two instructions are writing to the same location at
                the same time.

                I don't know if there are any such implementations , but there are
                definitely processors with multiple pipelines, so it could happen.
                --
                Flash Gordon
                Living in interesting times.
                Although my email address says spam, it is real and I read it.

                Comment

                • Mark McIntyre

                  #9
                  Re: why is it so ?

                  On 19 Jul 2005 04:10:33 -0700, in comp.lang.c ,
                  junky_fellow@ya hoo.co.in wrote:
                  [color=blue]
                  >Why
                  >
                  >i = ++i; is undefined
                  >but
                  >i = func(++i); is defined ?
                  >
                  >I know there is a sequence point after a call to a function
                  >after the arguments have been evaluated. But I am not able
                  >to visualise how the sequence point makes the second statement
                  >defined ?[/color]

                  At a sequence point, the effect of all preceding operations must be
                  complete. Therefore the effect of ++ must be complete. Therefore
                  passing it to a function is defined.
                  [color=blue]
                  >Also can someone give me a detailed explanation of
                  >why first statement is undefined ?[/color]

                  Axiomatically, the order in which things between sequence points are
                  done, is undefined.

                  --
                  Mark McIntyre
                  CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
                  CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt >

                  ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
                  http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
                  ----= East and West-Coast Server Farms - Total Privacy via Encryption =----

                  Comment

                  • Mark McIntyre

                    #10
                    Re: why is it so ?

                    On 19 Jul 2005 07:22:55 -0700, in comp.lang.c ,
                    junky_fellow@ya hoo.co.in wrote:

                    (of invoking UB via modifying an object twice between sequence points.
                    [color=blue]
                    >Still I don't understand what's the harm in doing that. Can
                    >you please show (step by step) how this will lead to different results
                    >on different complilers ?[/color]

                    First you tell us what the result is. Hint: there are multiple
                    possibilities, even excluding the use of parallel processor pipelines
                    to execute the store and increment.
                    --
                    Mark McIntyre
                    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
                    CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt >

                    ----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
                    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
                    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----

                    Comment

                    • Barry Schwarz

                      #11
                      Re: why is it so ?

                      On 19 Jul 2005 04:10:33 -0700, junky_fellow@ya hoo.co.in wrote:
                      [color=blue]
                      >Why
                      >
                      >i = ++i; is undefined
                      >but
                      >i = func(++i); is defined ?
                      >
                      >I know there is a sequence point after a call to a function
                      >after the arguments have been evaluated. But I am not able
                      >to visualise how the sequence point makes the second statement
                      >defined ? Also can someone give me a detailed explanation of
                      >why first statement is undefined ?
                      >[/color]
                      In the first example, the ++ operator returns the incremented value of
                      i but does not necessarily increment storage until a sequence point is
                      reached. The only sequence point is the terminating semicolon. So it
                      would be possible for the ++ operator to increment the value in i
                      before or after the value is changed by the = operator. This allows
                      for two different possible results in i which is obviously
                      intolerable. So the standard requires this to be undefined behavior.

                      In the second example, there is a sequence point after the argument is
                      evaluated but before the function is called. Therefore, the update to
                      i due to the ++ operator is performed before the function is called.
                      After the function returns, the value of i is updated again by the =
                      operator but there is no other update "pending" and therefore no
                      potential ambiguity.



                      <<Remove the del for email>>

                      Comment

                      • Eric Sosman

                        #12
                        Re: why is it so ?



                        Barry Schwarz wrote:[color=blue]
                        > On 19 Jul 2005 04:10:33 -0700, junky_fellow@ya hoo.co.in wrote:
                        >
                        >[color=green]
                        >>Why
                        >>
                        >>i = ++i; is undefined
                        >>but
                        >>i = func(++i); is defined ?
                        >>
                        >>I know there is a sequence point after a call to a function
                        >>after the arguments have been evaluated. But I am not able
                        >>to visualise how the sequence point makes the second statement
                        >>defined ? Also can someone give me a detailed explanation of
                        >>why first statement is undefined ?
                        >>[/color]
                        >
                        > In the first example, the ++ operator returns the incremented value of
                        > i but does not necessarily increment storage until a sequence point is
                        > reached. The only sequence point is the terminating semicolon. So it
                        > would be possible for the ++ operator to increment the value in i
                        > before or after the value is changed by the = operator. This allows
                        > for two different possible results in i which is obviously
                        > intolerable. So the standard requires this to be undefined behavior.
                        >
                        > In the second example, there is a sequence point after the argument is
                        > evaluated but before the function is called. Therefore, the update to
                        > i due to the ++ operator is performed before the function is called.
                        > After the function returns, the value of i is updated again by the =
                        > operator but there is no other update "pending" and therefore no
                        > potential ambiguity.[/color]

                        Personally, I've never been entirely convinced that
                        `i = f(++i)' is bulletproof. Yes, there's a sequence point
                        between evaluating `++i' and starting to execute `f', and
                        there's even another one before `f' returns its value. But
                        I don't think this guarantees a sequence point between the
                        evaluation of `++i' and the assignment to the l.h.s.

                        Now, "it stands to reason" that the assignment cannot
                        occur until after `f' returns its value, and `f' cannot
                        return its value until it's been called, so the sequence
                        point at the call should suffice. But I don't think this
                        argument is reliable: What if the compiler can predict the
                        value `f' will return without actually calling it at all?
                        For example,

                        int f(int x) {
                        printf ("%d bottles of beer on the wall\n", x);
                        return 0; /* 0 = success, -1 = failure */
                        }

                        is "predictabl e," and I think the compiler would be within
                        its rights to zero `i', call `f', and ignore the returned
                        value. Lord only knows what would happen to the `++',
                        or what might appear on stdout. Old Frothingslosh, if
                        your luck is bad.

                        --
                        Eric.Sosman@sun .com

                        Comment

                        • Robert Gamble

                          #13
                          Re: why is it so ?

                          Eric Sosman wrote:[color=blue]
                          > Barry Schwarz wrote:[color=green]
                          > > On 19 Jul 2005 04:10:33 -0700, junky_fellow@ya hoo.co.in wrote:
                          > >
                          > >[color=darkred]
                          > >>Why
                          > >>
                          > >>i = ++i; is undefined
                          > >>but
                          > >>i = func(++i); is defined ?
                          > >>
                          > >>I know there is a sequence point after a call to a function
                          > >>after the arguments have been evaluated. But I am not able
                          > >>to visualise how the sequence point makes the second statement
                          > >>defined ? Also can someone give me a detailed explanation of
                          > >>why first statement is undefined ?
                          > >>[/color]
                          > >
                          > > In the first example, the ++ operator returns the incremented value of
                          > > i but does not necessarily increment storage until a sequence point is
                          > > reached. The only sequence point is the terminating semicolon. So it
                          > > would be possible for the ++ operator to increment the value in i
                          > > before or after the value is changed by the = operator. This allows
                          > > for two different possible results in i which is obviously
                          > > intolerable. So the standard requires this to be undefined behavior.
                          > >
                          > > In the second example, there is a sequence point after the argument is
                          > > evaluated but before the function is called. Therefore, the update to
                          > > i due to the ++ operator is performed before the function is called.
                          > > After the function returns, the value of i is updated again by the =
                          > > operator but there is no other update "pending" and therefore no
                          > > potential ambiguity.[/color]
                          >
                          > Personally, I've never been entirely convinced that
                          > `i = f(++i)' is bulletproof. Yes, there's a sequence point
                          > between evaluating `++i' and starting to execute `f', and
                          > there's even another one before `f' returns its value. But
                          > I don't think this guarantees a sequence point between the
                          > evaluation of `++i' and the assignment to the l.h.s.
                          >
                          > Now, "it stands to reason" that the assignment cannot
                          > occur until after `f' returns its value, and `f' cannot
                          > return its value until it's been called, so the sequence
                          > point at the call should suffice. But I don't think this
                          > argument is reliable: What if the compiler can predict the
                          > value `f' will return without actually calling it at all?
                          > For example,
                          >
                          > int f(int x) {
                          > printf ("%d bottles of beer on the wall\n", x);
                          > return 0; /* 0 = success, -1 = failure */
                          > }
                          >
                          > is "predictabl e," and I think the compiler would be within
                          > its rights to zero `i', call `f', and ignore the returned
                          > value.[/color]

                          I don't think so. A very similiar example was provided recently in the
                          thread entitled "Sequence points and function calls" in comp.std.c. In
                          response, Peter Nilsson noted that such optimization "cannot induce
                          undefined behavior
                          in a case where the abstract semantics are well defined" and points out
                          an example in the Standard to support this statement (Example 6 in
                          5.1.2.3). Antoine Leca also noted "it is possible to allow the
                          compiler to
                          optimise by storing 0 in i early (or for example, on a different CPU),
                          but
                          not earlier than the fetch of the previous value of i to feed into the
                          call." and provided relevant citations from the Standard. I agree with
                          their reasoning and can't find fault with their arguments.

                          Robert Gamble

                          Comment

                          • Keith Thompson

                            #14
                            Re: why is it so ?

                            Eric Sosman <eric.sosman@su n.com> writes:
                            [...][color=blue]
                            > Personally, I've never been entirely convinced that
                            > `i = f(++i)' is bulletproof. Yes, there's a sequence point
                            > between evaluating `++i' and starting to execute `f', and
                            > there's even another one before `f' returns its value. But
                            > I don't think this guarantees a sequence point between the
                            > evaluation of `++i' and the assignment to the l.h.s.
                            >
                            > Now, "it stands to reason" that the assignment cannot
                            > occur until after `f' returns its value, and `f' cannot
                            > return its value until it's been called, so the sequence
                            > point at the call should suffice. But I don't think this
                            > argument is reliable: What if the compiler can predict the
                            > value `f' will return without actually calling it at all?
                            > For example,
                            >
                            > int f(int x) {
                            > printf ("%d bottles of beer on the wall\n", x);
                            > return 0; /* 0 = success, -1 = failure */
                            > }
                            >
                            > is "predictabl e," and I think the compiler would be within
                            > its rights to zero `i', call `f', and ignore the returned
                            > value. Lord only knows what would happen to the `++',
                            > or what might appear on stdout. Old Frothingslosh, if
                            > your luck is bad.[/color]

                            The whole purpose of sequence points, I think, is to impose a
                            reasonable set of of restrictions on what optimizations a compiler is
                            allowed to perform. An optimizer *can* move a side effect across a
                            sequence point, but it's allowed to do so only if it doesn't destroy
                            the semantics of the program. The actual program needs to behave,
                            within certain limits, in a manner consistent with the way the program
                            behaves in the C abstract machine.

                            For example:

                            int i = 3;
                            printf("i = %d\n", i);
                            i ++;

                            Moving the increment before the printf, causing it to print "i = 4",
                            would be non-conforming. I believe the transformation you describe
                            would be non-conforming for the same reasons.

                            But I'm not 100% certain that I'm correct about this, and I could
                            probably shoot some holes in my own arguments if I put my mind to it.

                            As a programmer, I'll just avoid things like "i = f(++i);". If I were
                            implementing a compiler, I'd try to be conservative enough in my
                            optimizations so that "i = f(++i);" works as expected, even if I can
                            justify breaking it by invoking undefined behavior if I squint while
                            reading the standard.

                            The real question is, if an implementation does something other than
                            the obvious for "i = f(++i);", can I complain about non-conformance in
                            my bug report? I *think* the answer is yes.

                            --
                            Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                            San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
                            We must do something. This is something. Therefore, we must do this.

                            Comment

                            • CBFalconer

                              #15
                              Re: why is it so ?

                              Keith Thompson wrote:[color=blue]
                              >[/color]
                              .... snip ...[color=blue]
                              >
                              > The real question is, if an implementation does something other
                              > than the obvious for "i = f(++i);", can I complain about non-
                              > conformance in my bug report? I *think* the answer is yes.[/color]

                              And who would ever write that when "i = f(i + 1);" works without
                              any question, and is even clear to the reader? ++ and -- are
                              overused IMO.

                              --
                              Chuck F (cbfalconer@yah oo.com) (cbfalconer@wor ldnet.att.net)
                              Available for consulting/temporary embedded and systems.
                              <http://cbfalconer.home .att.net> USE worldnet address!


                              Comment

                              Working...