Order of execution

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

    Order of execution

    Hi all,
    one of the recent post gives the macro to do swap

    #define SWAP(m, n) (tmp = (m), (m) = (n), (n) = tmp)

    This macro will work, if the execution is from left to right.

    That is step 1) tmp=m
    step 2) m=n
    step 3) n=tmp

    But I hope order of execution is decided by the compiler.
    Does C specification is saying any thing about this order of exectuion?

    Will this macro work on all compilers?

    Plz share your thoughts...

    Thanks
    Sabi

  • Roberto Waltman

    #2
    Re: Order of execution

    "Sabiyur" <SabiyurRahman@ gmail.com> wrote:[color=blue]
    >Hi all,
    > one of the recent post gives the macro to do swap
    >
    >#define SWAP(m, n) (tmp = (m), (m) = (n), (n) = tmp)
    >
    >This macro will work, if the execution is from left to right.
    >
    >That is step 1) tmp=m
    > step 2) m=n
    > step 3) n=tmp
    >
    >But I hope order of execution is decided by the compiler.
    >Does C specification is saying any thing about this order of exectuion?
    >
    >Will this macro work on all compilers?
    >[/color]
    Yes, it will work on all C compilers. The comma operator used in the
    macro guarantees left-to-right evaluation.

    (Of course, tmp must be defined first.)

    Comment

    • Richard Bos

      #3
      Re: Order of execution

      "Sabiyur" <SabiyurRahman@ gmail.com> wrote:
      [color=blue]
      > one of the recent post gives the macro to do swap
      >
      > #define SWAP(m, n) (tmp = (m), (m) = (n), (n) = tmp)
      >
      > This macro will work, if the execution is from left to right.[/color]

      No, it won't; it will work, _if_ (and that's a much bigger if) tmp has
      the same type as m and n, or a compatible one.
      [color=blue]
      > That is step 1) tmp=m
      > step 2) m=n
      > step 3) n=tmp
      >
      > But I hope order of execution is decided by the compiler.
      > Does C specification is saying any thing about this order of exectuion?[/color]

      Yes. Not generally, but there's a sequence point at the commas. This
      means that whatever trickery happens under the bonnet, the program much
      at least behave as if it was executed left-to-right.

      However, using this macro means that you have to declare a third object;
      this object _must_ be called tmp; it must not hold an important value at
      the moment this macro is called; and it must be declared to have a type
      that is compatible with both m and n (so no using it to swap long
      doubles one line, and structs the next line. So much for generality).

      All this means that using this macro is probably rather more bother than
      just writing this line out every time you need it. At least that means
      you can swap several types of value, without having to resort to hacks
      such as

      {
      the_appropriate _type tmp;
      SWAP(object_1, object_2_;
      }

      (Oh, and of course by forgoing the macro you can also swap objects which
      are themselves called tmp, but that's a lesser advantage.)

      Richard

      Comment

      • Michael Mair

        #4
        Re: Order of execution

        Sabiyur schrieb:[color=blue]
        > Hi all,
        > one of the recent post gives the macro to do swap
        >
        > #define SWAP(m, n) (tmp = (m), (m) = (n), (n) = tmp)
        >
        > This macro will work, if the execution is from left to right.
        >
        > That is step 1) tmp=m
        > step 2) m=n
        > step 3) n=tmp
        >
        > But I hope order of execution is decided by the compiler.
        > Does C specification is saying any thing about this order of exectuion?
        >
        > Will this macro work on all compilers?[/color]

        C has a concept called "sequence points".
        Between two consecutive sequence points, the order of execution
        is not determined by the C standard -- it only has to be
        semantically correct.
        However, you can be sure that the code before the sequence point
        is evaluated after the sequence point (or that your compiler /
        platform behaves as if this is the case).
        The comma operator gives you such a sequence point, i.e.
        the preprocessed version of
        tmp = (m)
        will be executed before the preprocessed version of
        (m) = (n), (n) = tmp
        and, applying this rule once more,
        (m) = (n)
        is executed before
        (n) = tmp

        Read more on sequence points in the FAQ:

        and the rest of chapter 3.

        Cheers
        Michael
        --
        E-Mail: Mine is an /at/ gmx /dot/ de address.

        Comment

        • Roberto Waltman

          #5
          Re: Order of execution

          Michael Mair wrote:
          [color=blue][color=green]
          >>...
          >>
          >> Will this macro work on all compilers?[/color]
          >
          >C has a concept called "sequence points".
          >Between two consecutive sequence points, the order of execution
          >is not determined by the C standard -- it only has to be
          >semantically correct.
          >However, you can be sure that the code before the sequence point
          >is evaluated <-----> after the sequence point (or that your compiler /[/color]

          Insert // "before the code that is" \\
          [color=blue]
          >platform behaves as if this is the case).
          >The comma operator gives you such a sequence point, i.e.
          >the preprocessed version of
          > tmp = (m)
          >will be executed before the preprocessed version of
          > (m) = (n), (n) = tmp
          >and, applying this rule once more,
          > (m) = (n)
          >is executed before
          > (n) = tmp
          >
          >Read more on sequence points in the FAQ:
          > http://c-faq.com/expr/seqpoints.html
          >and the rest of chapter 3.
          >
          >Cheers
          > Michael[/color]

          Comment

          • Michael Mair

            #6
            Re: Order of execution

            Roberto Waltman schrieb:[color=blue]
            > Michael Mair wrote:[color=green][color=darkred]
            >>>...
            >>>
            >>>Will this macro work on all compilers?[/color]
            >>
            >>C has a concept called "sequence points".
            >>Between two consecutive sequence points, the order of execution
            >>is not determined by the C standard -- it only has to be
            >>semanticall y correct.
            >>However, you can be sure that the code before the sequence point
            >>is evaluated <-----> after the sequence point (or that your compiler /[/color]
            >
            > Insert // "before the code that is" \\[/color]

            That's what I meant to write -- thank you :-)

            Cheers
            Michael
            [color=blue][color=green]
            >>platform behaves as if this is the case).[/color][/color]


            --
            E-Mail: Mine is an /at/ gmx /dot/ de address.

            Comment

            • Stephen Sprunk

              #7
              Re: Order of execution

              "Sabiyur" <SabiyurRahman@ gmail.com> wrote in message
              news:1151508526 .723269.281600@ m73g2000cwd.goo glegroups.com.. .[color=blue]
              > But I hope order of execution is decided by the compiler.
              > Does C specification is saying any thing about this order of exectuion?[/color]

              The compiler can do anything it wants as long as the resulting program
              behaves as if it did exactly what you said, i.e. it should be impossible to
              detect it's done anything differently.

              You'll see this "as if" rule referred to frequently on c.l.c.
              [color=blue]
              > Will this macro work on all compilers?[/color]

              It should work the same on any compiler (there's reasons it may fail, but it
              would fail on all in those cases).

              S

              --
              Stephen Sprunk "Stupid people surround themselves with smart
              CCIE #3723 people. Smart people surround themselves with
              K5SSS smart people who disagree with them." --Aaron Sorkin


              --
              Posted via a free Usenet account from http://www.teranews.com

              Comment

              • Chris Hills

                #8
                Re: Order of execution

                In article <1151508526.723 269.281600@m73g 2000cwd.googleg roups.com>,
                Sabiyur <SabiyurRahman@ gmail.com> writes[color=blue]
                >Hi all,
                > one of the recent post gives the macro to do swap
                >
                >#define SWAP(m, n) (tmp = (m), (m) = (n), (n) = tmp)
                >
                >This macro will work, if the execution is from left to right.
                >
                >That is step 1) tmp=m
                > step 2) m=n
                > step 3) n=tmp
                >
                >But I hope order of execution is decided by the compiler.
                >Does C specification is saying any thing about this order of exectuion?
                >
                >Will this macro work on all compilers?
                >
                >Plz share your thoughts...[/color]




                --
                \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
                \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/
                /\/\/ chris@phaedsys. org www.phaedsys.org \/\/\
                \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/



                Comment

                • gangchen.oz@gmail.com

                  #9
                  Re: Order of execution

                  the result I got from following calculation is (i=10, j=2):
                  (i * j++) + (i * j) = 40
                  (i * j) + (i * j++) = 40
                  (i * j--) + (i * j) = 40
                  (i * j) + (i * j--) = 40
                  (i * ++j) + (i * j) = 60
                  (i * j) + (i * ++j) = 60
                  (i * ++j) + (i * --j) = 40
                  (i * --j) + (i * ++j) = 40

                  I realized that the '+' operator is not a sequence point, which means
                  either left or right part could have side effects. Still feel a little
                  puzzled, please someone could explain this.

                  Comment

                  • Richard Heathfield

                    #10
                    Re: Order of execution

                    gangchen.oz@gma il.com said:
                    [color=blue]
                    > the result I got from following calculation is (i=10, j=2):
                    > (i * j++) + (i * j) = 40[/color]

                    Undefined behaviour.
                    [color=blue]
                    > (i * j) + (i * j++) = 40[/color]

                    Undefined behaviour.
                    [color=blue]
                    > (i * j--) + (i * j) = 40[/color]

                    Undefined behaviour.
                    [color=blue]
                    > (i * j) + (i * j--) = 40[/color]

                    Undefined behaviour.
                    [color=blue]
                    > (i * ++j) + (i * j) = 60[/color]

                    Undefined behaviour.
                    [color=blue]
                    > (i * j) + (i * ++j) = 60[/color]

                    Undefined behaviour.
                    [color=blue]
                    > (i * ++j) + (i * --j) = 40[/color]

                    Undefined behaviour.
                    [color=blue]
                    > (i * --j) + (i * ++j) = 40[/color]

                    Undefined behaviour.
                    [color=blue]
                    > I realized that the '+' operator is not a sequence point, which means
                    > either left or right part could have side effects. Still feel a little
                    > puzzled, please someone could explain this.[/color]

                    Undefined behaviour - and the C Standard does not attempt to explain or
                    predict the results of undefined behaviour.

                    In other words, when you break the rules, you're on your own.

                    --
                    Richard Heathfield
                    "Usenet is a strange place" - dmr 29/7/1999

                    email: rjh at above domain (but drop the www, obviously)

                    Comment

                    • Roberto Waltman

                      #11
                      Re: Order of execution

                      On 29 Jun 2006 08:37:28 -0700, gangchen.oz@gma il.com wrote:[color=blue]
                      >the result I got from following calculation is (i=10, j=2):
                      >(i * j++) + (i * j) = 40
                      >(i * j) + (i * j++) = 40
                      >(i * j--) + (i * j) = 40
                      >(i * j) + (i * j--) = 40
                      >(i * ++j) + (i * j) = 60
                      >(i * j) + (i * ++j) = 60
                      >(i * ++j) + (i * --j) = 40
                      >(i * --j) + (i * ++j) = 40
                      >
                      >I realized that the '+' operator is not a sequence point, which means
                      >either left or right part could have side effects.[/color]

                      The would "have side effects" (changing the value of j) even if there
                      was a sequence point.
                      [color=blue]
                      >Still feel a little
                      >puzzled, please someone could explain this.[/color]

                      They all invoke undefined behavior, so anything can happen.
                      Contrary to popular believe in comp.lang.c, this does not mean that
                      demons may fly out of your nose, but that the compiler is not required
                      to interpret these statements in any one well defined way, or to do
                      anything that is consistent and repeatable, or to do anything that
                      looks "reasonable " to you.

                      Let's take the first example:

                      /* result = */ (i * j++) + (i * j) /* ; */

                      A compiler could translate this as if it was written in either one of
                      the following ways (and an infinite number of others.). None of them
                      is "incorrect" .

                      (Lets assume i, j, tmp1, tmp2, tmp3 and result are all declared as
                      plain int.)

                      =====
                      tmp1 = i * j;
                      tmp2 = i * j;
                      j++;
                      result = tmp1 + tmp2;
                      ====
                      tmp1 = i * j;
                      j++;
                      tmp2 = i * j;
                      result = tmp1 + tmp2;
                      =====
                      tmp1 = i * j;
                      tmp3 = j;
                      j = A_RANDOM_VALUE; /* In some architectures */
                      /* with multiple execution */
                      /* units, the increment was */
                      /* scheduled to run in */
                      /* parallel with following */
                      /* code, and the value of j */
                      /* is retrieved before the */
                      /* operation has been */
                      /* completed. */
                      /* Some architectures could */
                      /* trap this and terminate */
                      /* the program here. */
                      tmp2 = i * j;
                      j = tmp3 + 1;
                      result = tmp1 + tmp2;
                      =====

                      Comment

                      • Richard Heathfield

                        #12
                        Re: Order of execution

                        Roberto Waltman said:

                        <UB code examples snipped>
                        [color=blue]
                        > They all invoke undefined behavior, so anything can happen.
                        > Contrary to popular believe in comp.lang.c, this does not mean that
                        > demons may fly out of your nose,[/color]

                        Chapter and verse, please. :-)

                        --
                        Richard Heathfield
                        "Usenet is a strange place" - dmr 29/7/1999

                        email: rjh at above domain (but drop the www, obviously)

                        Comment

                        • Kenneth Brody

                          #13
                          Re: Order of execution

                          Roberto Waltman wrote:[color=blue]
                          >
                          > On 29 Jun 2006 08:37:28 -0700, gangchen.oz@gma il.com wrote:[/color]
                          [...][color=blue][color=green]
                          > >Still feel a little
                          > >puzzled, please someone could explain this.[/color]
                          >
                          > They all invoke undefined behavior, so anything can happen.
                          > Contrary to popular believe in comp.lang.c, this does not mean that
                          > demons may fly out of your nose but that the compiler is not required
                          > to interpret these statements in any one well defined way, or to do
                          > anything that is consistent and repeatable, or to do anything that
                          > looks "reasonable " to you.[/color]
                          [...]

                          And causing demons to fly out your nose is a perfectly valid way to
                          "interpret these statements", as far as the standard is concerned.

                          While it is highly unlikely that a compiler writer will go out of
                          his way to cause such behavior, there is nothing stopping one from
                          creating such behavior, and such behavior would still be conforming
                          to the standard.

                          The odds are that behaviour of code with things like "j++ + j" will
                          be one of two scenarios (returning either "j+j" or "j+j+1", with j
                          being incremented by one in both cases), but that is only because
                          the compiler writer simply allowed the undefined behavior to be
                          ignored, and treated the "j++" as if it were any other instance of
                          "j++" in a valid statement.

                          However, "the odds are" is not the same as "the standard requires",
                          and "undefined behavior" is exactly that -- undefined. The standard
                          places absolutely no restrictions on the outcome, and does not
                          prohibit the creation of nasal demons.

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


                          Comment

                          • Chris Hills

                            #14
                            Re: Order of execution

                            In article <ftidnTWKOsGzZj 7ZRVny1g@bt.com >, Richard Heathfield
                            <invalid@invali d.invalid> writes[color=blue]
                            >gangchen.oz@gm ail.com said:
                            >[color=green]
                            >> the result I got from following calculation is (i=10, j=2):
                            >> (i * j++) + (i * j) = 40[/color]
                            >
                            >Undefined behaviour.
                            >[color=green]
                            >> (i * j) + (i * j++) = 40[/color]
                            >
                            >Undefined behaviour.
                            >[color=green]
                            >> (i * j--) + (i * j) = 40[/color]
                            >
                            >Undefined behaviour.
                            >[color=green]
                            >> (i * j) + (i * j--) = 40[/color]
                            >
                            >Undefined behaviour.
                            >[color=green]
                            >> (i * ++j) + (i * j) = 60[/color]
                            >
                            >Undefined behaviour.
                            >[color=green]
                            >> (i * j) + (i * ++j) = 60[/color]
                            >
                            >Undefined behaviour.
                            >[color=green]
                            >> (i * ++j) + (i * --j) = 40[/color]
                            >
                            >Undefined behaviour.
                            >[color=green]
                            >> (i * --j) + (i * ++j) = 40[/color]
                            >
                            >Undefined behaviour.
                            >[color=green]
                            >> I realized that the '+' operator is not a sequence point, which means
                            >> either left or right part could have side effects. Still feel a little
                            >> puzzled, please someone could explain this.[/color]
                            >
                            >Undefined behaviour - and the C Standard does not attempt to explain or
                            >predict the results of undefined behaviour.
                            >
                            >In other words, when you break the rules, you're on your own.
                            >[/color]

                            See the page linked to the one with the above lines


                            --
                            \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
                            \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/
                            /\/\/ chris@phaedsys. org www.phaedsys.org \/\/\
                            \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/



                            Comment

                            • Chris Hills

                              #15
                              Re: Order of execution

                              In article <1151595448.825 289.99870@j72g2 000cwa.googlegr oups.com>,
                              gangchen.oz@gma il.com writes[color=blue]
                              >the result I got from following calculation is (i=10, j=2):
                              >(i * j++) + (i * j) = 40
                              >(i * j) + (i * j++) = 40
                              >(i * j--) + (i * j) = 40
                              >(i * j) + (i * j--) = 40
                              >(i * ++j) + (i * j) = 60
                              >(i * j) + (i * ++j) = 60
                              >(i * ++j) + (i * --j) = 40
                              >(i * --j) + (i * ++j) = 40
                              >
                              >I realized that the '+' operator is not a sequence point, which means
                              >either left or right part could have side effects. Still feel a little
                              >puzzled, please someone could explain this.[/color]

                              There is no defined way of processing a line. Some work left to right
                              others right to left and some middle out etc. With others it depends on
                              how the optimiser works on that particular architecture as to how it
                              does it.


                              I assume everyone also looked at the linked page



                              which gave the outputs from several compilers highlighting the fact that
                              it is all Undefined Behaviour.

                              As it happens that line of above "results" is not the same as the other
                              FIVE versions recorded!!!

                              What was the compiler used? Does any one have any more differing
                              results. I will expand the table.


                              --
                              \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
                              \/\/\/\/\ Chris Hills Staffs England /\/\/\/\/
                              /\/\/ chris@phaedsys. org www.phaedsys.org \/\/\
                              \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/



                              Comment

                              Working...