Loading ...
Sorry, an error occurred while loading the content.

Re: Mainly noise

Expand Messages
  • James Widman
    Hi Marcus, ... My apologies. I applied intuition to form an opinion about this, and it turns out that opinion was incorrect. Sorry people; I m new here. Then
    Message 1 of 18 , Jul 4, 2005
    • 0 Attachment
      Hi Marcus,

      On Jul 4, 2005, at 2:09 PM, Marcus Aurelius wrote:

      > --- James Widman <widman@...> escreveu:
      >
      >
      >>> 3) --- Module: main.c
      >>> while (((p = vim_strchr(++p, '/')) != NULL) && p[-1] == '\\')
      >>> ^
      >>> farsi.c(1954) : Warning 564: variable 'p' depends on order of
      >>> evaluation
      >>>
      >>> I think this message is probably spurious.
      >>>
      >>
      >> Yes, definitely; I think we're reporting because the order of
      >> evaluation of operands to the assignment operator is unspecified and
      >> because 'p' appeared somewhere on both sides and was modified on at
      >> least one. Of course, that doesn't matter in this case since the
      >> value of s is not being used to determine where the result of the
      >> expression will be stored. Clearly, our analysis should be refined
      >> here.
      >>
      >
      > Maybe i'm missing something, but i can't see how this could be
      > correct:
      > ...(p = vim_strchr(++p, '/'))...
      > p is incremented and then assigned to. Isn't this similar to "i = +
      > +i"?
      > I'm not an expert about sequence points, but i guess it's undefined
      > behavior...

      My apologies. I applied intuition to form an opinion about this, and
      it turns out that opinion was incorrect.

      Sorry people; I'm new here.

      Then again, I'm on weekend/holiday time. FWIW. (;

      Excuses, excuses...

      Anyway: (i = ++i) seems, at first glance, like a safe (albeit
      questionable) expression. One might think (as I did) that,
      regardless of which side of '=' is evaluated first, the result is
      the same. But ISO C99, section 6.5,p2 says:

      "Between the previous and next sequence point an object shall have
      its stored value modified at most once by the evaluation of an
      expression."

      So according to C99, (p = vim_strchr(++p, '/')) results in undefined
      behavior because p is modified twice.

      ISO C++ has basically the same verbiage. I don't have our copies of
      ISO C90 or the first-edition K&R C book nearby, so I don't yet know
      the situation there.

      James Widman
      --
      Gimpel Software
      http://gimpel.com
    • Bram Moolenaar
      ... The problem here is the standard. C99 is probably the worst C standard that was ever made. It was clearly formed by politicians, not by practical
      Message 2 of 18 , Jul 5, 2005
      • 0 Attachment
        James Widman wrote:

        > Anyway: (i = ++i) seems, at first glance, like a safe (albeit
        > questionable) expression. One might think (as I did) that,
        > regardless of which side of '=' is evaluated first, the result is
        > the same. But ISO C99, section 6.5,p2 says:
        >
        > "Between the previous and next sequence point an object shall have
        > its stored value modified at most once by the evaluation of an
        > expression."
        >
        > So according to C99, (p = vim_strchr(++p, '/')) results in undefined
        > behavior because p is modified twice.
        >
        > ISO C++ has basically the same verbiage. I don't have our copies of
        > ISO C90 or the first-edition K&R C book nearby, so I don't yet know
        > the situation there.

        The problem here is the standard. C99 is probably the worst C standard
        that was ever made. It was clearly formed by politicians, not by
        practical programmers. OK, well, that's just my opinion (a ran into a
        couple of annoying problems).

        That "undefined behavior" is stupid. Of course every good-old C
        programmer can predict what should and will happen. Only very bad C
        compilers would not be able to deal with it. The standard should be
        adjusted to meet what programmers do and expect, not the other way
        around.

        --
        You can tune a file system, but you can't tuna fish
        -- man tunefs

        /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
        /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
        \\\ Project leader for A-A-P -- http://www.A-A-P.org ///
        \\\ Buy LOTR 3 and help AIDS victims -- http://ICCF.nl/lotr.html ///
      • Mike Williams
        ... I would hope any good-old C programmer would spot the possibility of undefined behaviour and rewrite the expression to remove the problem. On some
        Message 3 of 18 , Jul 5, 2005
        • 0 Attachment
          Bram Moolenaar did utter on 05/07/2005 10:29:
          > James Widman wrote:
          >
          >
          >>Anyway: (i = ++i) seems, at first glance, like a safe (albeit
          >>questionable) expression. One might think (as I did) that,
          >>regardless of which side of '=' is evaluated first, the result is
          >>the same. But ISO C99, section 6.5,p2 says:
          >>
          >>"Between the previous and next sequence point an object shall have
          >>its stored value modified at most once by the evaluation of an
          >>expression."
          >>
          >>So according to C99, (p = vim_strchr(++p, '/')) results in undefined
          >>behavior because p is modified twice.
          >>
          >>ISO C++ has basically the same verbiage. I don't have our copies of
          >>ISO C90 or the first-edition K&R C book nearby, so I don't yet know
          >>the situation there.
          >
          >
          > The problem here is the standard. C99 is probably the worst C standard
          > that was ever made. It was clearly formed by politicians, not by
          > practical programmers. OK, well, that's just my opinion (a ran into a
          > couple of annoying problems).
          >
          > That "undefined behavior" is stupid. Of course every good-old C
          > programmer can predict what should and will happen. Only very bad C
          > compilers would not be able to deal with it. The standard should be
          > adjusted to meet what programmers do and expect, not the other way
          > around.

          I would hope any good-old C programmer would spot the possibility of
          undefined behaviour and rewrite the expression to remove the problem.
          On some processors a good optimising compiler (producing correct fast
          code for well defined C) would fail with this invalid code. Side
          effects and sequence points are standard fare for any C job interview.

          TTFN

          Mike
          --
          Is there a lawyer in the house? <BLAM!!> Is there another?
        • James Widman
          ... FYI, this is not new text in C99. Those exact words appear in C89/90 section 3.3,p2. I cannot find anything so strict in the first K&R C book. ... I fail
          Message 4 of 18 , Jul 5, 2005
          • 0 Attachment
            On Jul 5, 2005, at 5:29 AM, Bram Moolenaar wrote:

            >
            > James Widman wrote:
            >
            >
            >> Anyway: (i = ++i) seems, at first glance, like a safe (albeit
            >> questionable) expression. One might think (as I did) that,
            >> regardless of which side of '=' is evaluated first, the result is
            >> the same. But ISO C99, section 6.5,p2 says:
            >>
            >> "Between the previous and next sequence point an object shall have
            >> its stored value modified at most once by the evaluation of an
            >> expression."


            FYI, this is not new text in C99. Those exact words appear in C89/90
            section 3.3,p2. I cannot find anything so strict in the first K&R C
            book.


            >> So according to C99, (p = vim_strchr(++p, '/')) results in undefined
            >> behavior because p is modified twice.
            >>
            >> ISO C++ has basically the same verbiage. I don't have our copies of
            >> ISO C90 or the first-edition K&R C book nearby, so I don't yet know
            >> the situation there.
            >>
            >
            > The problem here is the standard. C99 is probably the worst C
            > standard
            > that was ever made. It was clearly formed by politicians, not by
            > practical programmers. OK, well, that's just my opinion (a ran into a
            > couple of annoying problems).
            >
            > That "undefined behavior" is stupid. Of course every good-old C
            > programmer can predict what should and will happen. Only very bad C
            > compilers would not be able to deal with it.

            I fail to see how anything could actually go wrong with (i = ++i);
            perhaps there are issues associated with optimization. To me, a more
            likely reason for this rule is that the committee had plenty of work
            to do as it was; they were (and still are) on short schedules and
            were (and still are) volunteers. So they probably wanted to keep the
            normative text as simple as possible.

            The fact that it rendered expressions like (i = ++i) invalid was
            probably considered and deemed to have little importance since those
            expressions can easily be rewritten such that behavior is well-defined.

            > The standard should be adjusted to meet what programmers do and
            > expect, not the other way around.

            You'll find people who agree with you in both committees.

            James Widman
            --
            Gimpel Software
            http://gimpel.com
          • Matthew Winn
            ... It s undefined so the compiler can do it as efficiently as possible. On an architecture where transferring information from the stack to memory is fast, an
            Message 5 of 18 , Jul 5, 2005
            • 0 Attachment
              On Tue, Jul 05, 2005 at 11:29:51AM +0200, Bram Moolenaar wrote:
              >
              > James Widman wrote:
              >
              > > Anyway: (i = ++i) seems, at first glance, like a safe (albeit
              > > questionable) expression. One might think (as I did) that,
              > > regardless of which side of '=' is evaluated first, the result is
              > > the same. But ISO C99, section 6.5,p2 says:
              > >
              > > "Between the previous and next sequence point an object shall have
              > > its stored value modified at most once by the evaluation of an
              > > expression."
              > >
              > > So according to C99, (p = vim_strchr(++p, '/')) results in undefined
              > > behavior because p is modified twice.
              > >
              > > ISO C++ has basically the same verbiage. I don't have our copies of
              > > ISO C90 or the first-edition K&R C book nearby, so I don't yet know
              > > the situation there.
              >
              > The problem here is the standard. C99 is probably the worst C standard
              > that was ever made. It was clearly formed by politicians, not by
              > practical programmers. OK, well, that's just my opinion (a ran into a
              > couple of annoying problems).
              >
              > That "undefined behavior" is stupid. Of course every good-old C
              > programmer can predict what should and will happen. Only very bad C
              > compilers would not be able to deal with it. The standard should be
              > adjusted to meet what programmers do and expect, not the other way
              > around.

              It's undefined so the compiler can do it as efficiently as possible.
              On an architecture where transferring information from the stack to
              memory is fast, an expression like q = func(++p) may be fastest if the
              incremented value of p isn't written back to the correct memory location
              until after q has been altered. Why should either speed of execution
              or speed of compilation suffer just to deal with the special case where
              a programmer attempts to alter the same value two different ways in
              one expression, especially as p = func(p+1) is almost certainly more
              efficient than p = func(++p) anyway?

              --
              Matthew Winn (matthew@...)
            • Bram Moolenaar
              ... I m glad I don t have to do that job interview :-). Of course it s not clean programming to change a pointer twice, but in rare situations it happens. It s
              Message 6 of 18 , Jul 5, 2005
              • 0 Attachment
                Mike Williams wrote:

                > > James Widman wrote:
                > >
                > >>Anyway: (i = ++i) seems, at first glance, like a safe (albeit
                > >>questionable) expression. One might think (as I did) that,
                > >>regardless of which side of '=' is evaluated first, the result is
                > >>the same. But ISO C99, section 6.5,p2 says:
                > >>
                > >>"Between the previous and next sequence point an object shall have
                > >>its stored value modified at most once by the evaluation of an
                > >>expression."
                > >>
                > >>So according to C99, (p = vim_strchr(++p, '/')) results in undefined
                > >>behavior because p is modified twice.
                > >>
                > >>ISO C++ has basically the same verbiage. I don't have our copies of
                > >>ISO C90 or the first-edition K&R C book nearby, so I don't yet know
                > >>the situation there.
                > >
                > >
                > > The problem here is the standard. C99 is probably the worst C standard
                > > that was ever made. It was clearly formed by politicians, not by
                > > practical programmers. OK, well, that's just my opinion (a ran into a
                > > couple of annoying problems).
                > >
                > > That "undefined behavior" is stupid. Of course every good-old C
                > > programmer can predict what should and will happen. Only very bad C
                > > compilers would not be able to deal with it. The standard should be
                > > adjusted to meet what programmers do and expect, not the other way
                > > around.
                >
                > I would hope any good-old C programmer would spot the possibility of
                > undefined behaviour and rewrite the expression to remove the problem.
                > On some processors a good optimising compiler (producing correct fast
                > code for well defined C) would fail with this invalid code. Side
                > effects and sequence points are standard fare for any C job interview.

                I'm glad I don't have to do that job interview :-).

                Of course it's not clean programming to change a pointer twice, but in
                rare situations it happens.

                It's obvious to me that the assignment always happens after evaluating
                the expression on the RHS. No optimizer should ignore the side effects
                evaluating the expression might have. Also keep in mind that the "++p"
                could be in a preprocessor macro and be unnoticable for the programmer
                (esp. if someone changes the header file after you wrote the code!).

                If the optimizer breaks this I would say the optimizer is broken. If I
                have to read the details of the C standard to find something isn't
                guaranteed to work, while the code looks fine to the average programmer,
                then the C standard is broken, it doesn't do what "should happen".
                Fortunately most compiler builders know this and define the undefined
                behavior in the way most programmers expect it to work.

                --
                hundred-and-one symptoms of being an internet addict:
                245. You use Real Audio to listen to a radio station from a distant
                city rather than turn on your stereo system.

                /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
                /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
                \\\ Project leader for A-A-P -- http://www.A-A-P.org ///
                \\\ Buy LOTR 3 and help AIDS victims -- http://ICCF.nl/lotr.html ///
              • Bram Moolenaar
                ... Well, the compiler can see whether the resulting value of p is used or not, thus it can figure out what to do. ... In my opinion the easy of use of the
                Message 7 of 18 , Jul 5, 2005
                • 0 Attachment
                  Matthew Winn wrote:

                  > On Tue, Jul 05, 2005 at 11:29:51AM +0200, Bram Moolenaar wrote:
                  > >
                  > > James Widman wrote:
                  > >
                  > > > Anyway: (i = ++i) seems, at first glance, like a safe (albeit
                  > > > questionable) expression. One might think (as I did) that,
                  > > > regardless of which side of '=' is evaluated first, the result is
                  > > > the same. But ISO C99, section 6.5,p2 says:
                  > > >
                  > > > "Between the previous and next sequence point an object shall have
                  > > > its stored value modified at most once by the evaluation of an
                  > > > expression."
                  > > >
                  > > > So according to C99, (p = vim_strchr(++p, '/')) results in undefined
                  > > > behavior because p is modified twice.
                  > > >
                  > > > ISO C++ has basically the same verbiage. I don't have our copies of
                  > > > ISO C90 or the first-edition K&R C book nearby, so I don't yet know
                  > > > the situation there.
                  > >
                  > > The problem here is the standard. C99 is probably the worst C standard
                  > > that was ever made. It was clearly formed by politicians, not by
                  > > practical programmers. OK, well, that's just my opinion (a ran into a
                  > > couple of annoying problems).
                  > >
                  > > That "undefined behavior" is stupid. Of course every good-old C
                  > > programmer can predict what should and will happen. Only very bad C
                  > > compilers would not be able to deal with it. The standard should be
                  > > adjusted to meet what programmers do and expect, not the other way
                  > > around.
                  >
                  > It's undefined so the compiler can do it as efficiently as possible.
                  > On an architecture where transferring information from the stack to
                  > memory is fast, an expression like q = func(++p) may be fastest if the
                  > incremented value of p isn't written back to the correct memory location
                  > until after q has been altered.

                  Well, the compiler can see whether the resulting value of p is used or
                  not, thus it can figure out what to do.

                  > Why should either speed of execution
                  > or speed of compilation suffer just to deal with the special case where
                  > a programmer attempts to alter the same value two different ways in
                  > one expression, especially as p = func(p+1) is almost certainly more
                  > efficient than p = func(++p) anyway?

                  In my opinion the "easy of use" of the language is much, much more
                  important than the easy to write a compiler for it. After all,
                  programming languages are there to form the interface between a human
                  and a computer. We can tell the computer to do whatever we want it to
                  do, that is quite a bit more difficult for humans :-).

                  It's possible for the compiler (or optimizer) to see the side effect and
                  act accordingly. If there is no side effect, then use the optimal
                  implementation for speed. If there is a side effect then make sure it
                  works as the programmer expects.

                  This does make the compiler (optimizer) a bit more complex, but that's
                  an order of magnitude less important than having the teach the human to
                  avoid this construct. It's something you solve once and enjoy forever.

                  --
                  hundred-and-one symptoms of being an internet addict:
                  246. You use up your free 100 hours in less than a week.

                  /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
                  /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
                  \\\ Project leader for A-A-P -- http://www.A-A-P.org ///
                  \\\ Buy LOTR 3 and help AIDS victims -- http://ICCF.nl/lotr.html ///
                • Mike Williams
                  ... Why do you say obvious? By what definition? In C, assignment is no different to any other operator in an expression, which is why = is called the
                  Message 8 of 18 , Jul 5, 2005
                  • 0 Attachment
                    Bram Moolenaar did utter on 05/07/2005 15:57:

                    > I'm glad I don't have to do that job interview :-).
                    >
                    > Of course it's not clean programming to change a pointer twice, but in
                    > rare situations it happens.
                    >
                    > It's obvious to me that the assignment always happens after evaluating
                    > the expression on the RHS.

                    Why do you say obvious? By what definition? In C, assignment is no
                    different to any other operator in an expression, which is why = is
                    called the assigment operator. Assignment is not a statement like in
                    BASIC, Pascal, or Python, which is why you can do assignments within if,
                    while, etc. expressions. Being an expression, the order of evaluation
                    of the left and right hand sides of the assignment operator can be done
                    in any order as per any other operator's operands. All that the
                    standard specifies is that all side effects are resolved by the next
                    sequence point, nothing is said about the order of resolution between
                    sequence points.

                    > No optimizer should ignore the side effects
                    > evaluating the expression might have.

                    In C the term "side effect" has a defined meaning, which is essentially
                    modification of the execution state, i.e. the values of variables in
                    registers and memory. So the simple expression i = 1; contains "side
                    effects" due to setting the variable i to the value 1. "Side effects"
                    does not mean additional changes to the ones intended as possibly
                    understood with the ++/-- operators.

                    > Also keep in mind that the "++p"
                    > could be in a preprocessor macro and be unnoticable for the programmer
                    > (esp. if someone changes the header file after you wrote the code!).

                    Indeed, and another typical C interview question where an argument to a
                    macro is something like "p++" and the argument appears twice in the body
                    of the macro leading to undefined behaviour (the increment may happen
                    once or twice). Such macros should be written function like and macro
                    args assigned to block local variables to ensure the argument is
                    evaluated only once.

                    > If the optimizer breaks this I would say the optimizer is broken. If I
                    > have to read the details of the C standard to find something isn't
                    > guaranteed to work, while the code looks fine to the average programmer,
                    > then the C standard is broken, it doesn't do what "should happen".

                    The benefit of C's approach is that the optimizer is simpler and
                    therefore less bug prone. It is also more flexible across many
                    processor architectures providing efficient operation (smaller faster
                    binaries). Remember that C is used with more embedded processors than
                    PCs where saving bytes and cycles multiplies into big money quickly.

                    Some might say that a lot of the issues with copmuters is because
                    average programmers don't actually understand the tools they use. And C
                    is one of the simpler programming languages out there.

                    > Fortunately most compiler builders know this and define the undefined
                    > behavior in the way most programmers expect it to work.

                    I think you more mean that the few compilers on a couple of processor
                    architectures you are aware of happen to work in the way the code was
                    intended to work. I haven't seen different compilers for the same
                    processor behave differently, but I have seen the issue appear when
                    porting to other processors. Don't underestimate the benefit of jobs
                    running 10% faster due to optimisations possible from this flexibility in C.

                    Ok, this has gone way off topic. Normal service (and lurking) will be
                    resumed. ;-)

                    TTFN

                    Mike
                    --
                    The decision is maybe and that's final.
                  • Matthew Winn
                    ... What does p = func(++p) _mean_? You re assigning two different values to p at the same time: you re trying to give p the value p+1 and the return value of
                    Message 9 of 18 , Jul 6, 2005
                    • 0 Attachment
                      On Tue, Jul 05, 2005 at 06:15:19PM +0200, Bram Moolenaar wrote:
                      >
                      > Matthew Winn wrote:
                      > > Why should either speed of execution
                      > > or speed of compilation suffer just to deal with the special case where
                      > > a programmer attempts to alter the same value two different ways in
                      > > one expression, especially as p = func(p+1) is almost certainly more
                      > > efficient than p = func(++p) anyway?
                      >
                      > In my opinion the "easy of use" of the language is much, much more
                      > important than the easy to write a compiler for it. After all,
                      > programming languages are there to form the interface between a human
                      > and a computer. We can tell the computer to do whatever we want it to
                      > do, that is quite a bit more difficult for humans :-).

                      What does p = func(++p) _mean_? You're assigning two different values
                      to p at the same time: you're trying to give p the value p+1 and the
                      return value of func(). It's like saying int i = 1 = 2 and expecting
                      it to do both. If you mean p = func(p+1) then say p = func(p+1): it'll
                      execute faster and it's easier for readers to understand.

                      In the case of expressions like i = ++i both assignments to i have the
                      same value, so it's easy to claim that it's obvious what should happen,
                      but what about less obvious cases? What should
                      int i = 1;
                      i = ++i + ++i;
                      mean? I can think of ways in which that could give any integer result
                      from 2 to 6 depending on the order in which registers are allocated and
                      the way values are incremented and stored. It's easy to say that the
                      compiler should work out what was intended, but if humans can't decide
                      what was intended how can a compiler written by humans do it?

                      It's poor coding practice not only because the compiler's behaviour is
                      undefined, but also because anyone reading the source has to work harder
                      to determine the intention of the code. If I saw
                      p = vim_strchr(++p, '/');
                      I wouldn't know whether the "++p" was a mistake and should be "p+1", or
                      whether the "p =" was a mistake and the value was being assigned to the
                      wrong variable, or even whether the "++p" was a mistake and the wrong
                      variable was being incremented. As written that code makes no sense,
                      and if I can't work out what it means the compiler certainly shouldn't.

                      --
                      Matthew Winn (matthew@...)
                    • Bram Moolenaar
                      ... Order of evaluation for = is right to left. I expect the expression on the right to be evaluated before the result is assigned to the lvalue on the
                      Message 10 of 18 , Jul 6, 2005
                      • 0 Attachment
                        Matthew Winn wrote:

                        > What does p = func(++p) _mean_? You're assigning two different values
                        > to p at the same time: you're trying to give p the value p+1 and the
                        > return value of func(). It's like saying int i = 1 = 2 and expecting
                        > it to do both. If you mean p = func(p+1) then say p = func(p+1): it'll
                        > execute faster and it's easier for readers to understand.

                        Order of evaluation for "=" is right to left. I expect the expression
                        on the right to be evaluated before the result is assigned to the lvalue
                        on the left. Isn't that what everybody expects? You can't assign a
                        value before you know what the value is...

                        Another example where order of evaluation matters:

                        n = (getc(fd) << 8) + getc(fd);

                        The expression with "+" is evaluated from left to right, thus the first
                        read byte is shifted. This is not unusual code, right?

                        Adding up three byte values and putting the result in the fourth byte:

                        *p = *p++ + *p++ + *p++;

                        It's weird, but I don't think that it is unclear about what is expected
                        to happen.

                        > In the case of expressions like i = ++i both assignments to i have the
                        > same value, so it's easy to claim that it's obvious what should happen,
                        > but what about less obvious cases? What should
                        > int i = 1;
                        > i = ++i + ++i;
                        > mean? I can think of ways in which that could give any integer result
                        > from 2 to 6 depending on the order in which registers are allocated and
                        > the way values are incremented and stored. It's easy to say that the
                        > compiler should work out what was intended, but if humans can't decide
                        > what was intended how can a compiler written by humans do it?

                        If you know that evaluating the expression is done before the assignment
                        then it's clear what should happen. But your example is unrealistic,
                        there is no point in doing the second increment.

                        Order of evaluation matters in many cases, thus it's not at all strange
                        to define this for the assignment. Most notably for C is:

                        if (p != NULL && *p == 1)

                        The && operator involves evaluating from left to right, and once it's
                        clear the result is False the evaluation stops. This is defined in the
                        standard, right? Otherwise a lot of code would break...

                        > It's poor coding practice not only because the compiler's behaviour is
                        > undefined, but also because anyone reading the source has to work harder
                        > to determine the intention of the code. If I saw
                        > p = vim_strchr(++p, '/');
                        > I wouldn't know whether the "++p" was a mistake and should be "p+1", or
                        > whether the "p =" was a mistake and the value was being assigned to the
                        > wrong variable, or even whether the "++p" was a mistake and the wrong
                        > variable was being incremented. As written that code makes no sense,
                        > and if I can't work out what it means the compiler certainly shouldn't.

                        Right, the ++p doesn't make sense here, since the result of the
                        increment doesn't need to be stored. The code isn't written like that,
                        the increment is done in a macro. The code did make sense before
                        expanding the macro. The macro might be suspicious, but isn't using
                        macros anyway?

                        --
                        Vi is clearly superior to emacs, since "vi" has only two characters
                        (and two keystrokes), while "emacs" has five. (Randy C. Ford)

                        /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
                        /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
                        \\\ Project leader for A-A-P -- http://www.A-A-P.org ///
                        \\\ Buy LOTR 3 and help AIDS victims -- http://ICCF.nl/lotr.html ///
                      • Mike Williams
                        [ I feel there is much spleen venting going on here ;-) ] ... No it is not. _Association_ for = is right to left, but the order of evaluation of the
                        Message 11 of 18 , Jul 6, 2005
                        • 0 Attachment
                          [ I feel there is much spleen venting going on here ;-) ]

                          Bram Moolenaar did utter on 06/07/2005 10:40:
                          > Matthew Winn wrote:
                          >
                          >>What does p = func(++p) _mean_? You're assigning two different values
                          >>to p at the same time: you're trying to give p the value p+1 and the
                          >>return value of func(). It's like saying int i = 1 = 2 and expecting
                          >>it to do both. If you mean p = func(p+1) then say p = func(p+1): it'll
                          >>execute faster and it's easier for readers to understand.
                          >
                          > Order of evaluation for "=" is right to left.

                          No it is not. _Association_ for "=" is right to left, but the order of
                          evaluation of the operands of the "=" operator is undefined. Given the
                          expresion a[i] = 2*b; a C compiler is allowed to calculate the memory
                          address for a[i] before evaluating the value 2*b, but doesn't have to.

                          > I expect the expression
                          > on the right to be evaluated before the result is assigned to the lvalue
                          > on the left. Isn't that what everybody expects?

                          They may expect it but they would be wrong. Consider the expression
                          a[i++] = i; with i being 0 - what would you expect, and why? And of
                          course you will be wrong ;-)

                          > You can't assign a
                          > value before you know what the value is...

                          The issue is that the expression of the object you assign the value to
                          has to be evaluated as well as the expression that generates the value
                          being assigned. It is the order of these evaluations that is undefined.

                          > Another example where order of evaluation matters:
                          >
                          > n = (getc(fd) << 8) + getc(fd);
                          >
                          > The expression with "+" is evaluated from left to right, thus the first
                          > read byte is shifted. This is not unusual code, right?
                          >
                          > Adding up three byte values and putting the result in the fourth byte:
                          >
                          > *p = *p++ + *p++ + *p++;
                          >
                          > It's weird, but I don't think that it is unclear about what is expected
                          > to happen.

                          That may be so but in both cases it is potentially buggy code. If you
                          write code for a single platform/processor and it works for you then you
                          may be happy leaving it as it is, but if you want to write portable
                          code, including for new processors/platforms yet to appear, it should be
                          corrected.

                          >>In the case of expressions like i = ++i both assignments to i have the
                          >>same value, so it's easy to claim that it's obvious what should happen,
                          >>but what about less obvious cases? What should
                          >> int i = 1;
                          >> i = ++i + ++i;
                          >>mean? I can think of ways in which that could give any integer result
                          >>from 2 to 6 depending on the order in which registers are allocated and
                          >>the way values are incremented and stored. It's easy to say that the
                          >>compiler should work out what was intended, but if humans can't decide
                          >>what was intended how can a compiler written by humans do it?
                          >
                          >
                          > If you know that evaluating the expression is done before the assignment
                          > then it's clear what should happen. But your example is unrealistic,
                          > there is no point in doing the second increment.
                          >
                          > Order of evaluation matters in many cases, thus it's not at all strange
                          > to define this for the assignment.

                          Evaluation is defined in terms of "sequence points" not operators. A
                          sequence point is the point in execution at which all side effects from
                          an evluation prior to point are complete and no side effects have
                          started for an evaluation after the point.

                          > Most notably for C is:
                          >
                          > if (p != NULL && *p == 1)
                          >
                          > The && operator involves evaluating from left to right, and once it's
                          > clear the result is False the evaluation stops. This is defined in the
                          > standard, right? Otherwise a lot of code would break...

                          The logical operators && and || are special cases since they allow a
                          speed optimisation in conditional expressions. There are programming
                          languages where the complete conditional expression is evaluated, which
                          would result in the above example causing a crash. Who is to say which
                          is the natural way? This can be very confusing to those new to
                          short-circuiting conditional expressions.

                          >>It's poor coding practice not only because the compiler's behaviour is
                          >>undefined, but also because anyone reading the source has to work harder
                          >>to determine the intention of the code. If I saw
                          >> p = vim_strchr(++p, '/');
                          >>I wouldn't know whether the "++p" was a mistake and should be "p+1", or
                          >>whether the "p =" was a mistake and the value was being assigned to the
                          >>wrong variable, or even whether the "++p" was a mistake and the wrong
                          >>variable was being incremented. As written that code makes no sense,
                          >>and if I can't work out what it means the compiler certainly shouldn't.
                          >
                          > Right, the ++p doesn't make sense here, since the result of the
                          > increment doesn't need to be stored. The code isn't written like that,
                          > the increment is done in a macro. The code did make sense before
                          > expanding the macro. The macro might be suspicious, but isn't using
                          > macros anyway?

                          TTFN

                          Mike
                          --
                          There are two ways to handle women. I don't know either one.
                        • Walter Briscoe
                          In message of Wed, 6 Jul 2005 11:40:44 in , Bram Moolenaar writes [snip] ... Bram, I think you
                          Message 12 of 18 , Jul 6, 2005
                          • 0 Attachment
                            In message <200507060940.j669eiwS058980@...> of Wed, 6 Jul
                            2005 11:40:44 in , Bram Moolenaar <Bram@...> writes

                            [snip]

                            >Right, the ++p doesn't make sense here, since the result of the
                            >increment doesn't need to be stored. The code isn't written like that,
                            >the increment is done in a macro. The code did make sense before
                            >expanding the macro. The macro might be suspicious, but isn't using
                            >macros anyway?
                            >

                            Bram,
                            I think you mis-remember.
                            We have farsi.c(1954): while (((p = vim_strchr(++p, '/')) != NULL) && p[-1] == '\\')
                            I have main.i(316897): while (((p = vim_strchr(++p, '/')) != ((void *)0)) && p[-1] == '\\')

                            I don't think there is anything unsafe about the code.
                            There is a sequence point before the call of vim_strchr.
                            There is another sequence point at && which means that p p[-1] refers to
                            the result of the assignment rather than the result of the increment.
                            Appendix C on sequence points in the C99 standard is helpful.

                            My proposed fix looks like c**p to me now. Do you agree this is clearer:
                            while (((p = vim_strchr(p+1, '/')) != NULL) && p[-1] == '\\')

                            As I said, I think PC-lint's sequence point model is adequate given its
                            purpose. This is the only vim thing [which] the simpler model diagnoses.
                            I insert that [which] to clarify my meaning. It is not strictly needed.
                            I think it improves my words. I first used "flags" where I now use
                            "diagnoses". It is sometimes hard to find an English verb which is not
                            also a noun and, so, requires more complicated syntax analysis.

                            Here, those whose first language is not English, do brilliantly, IMHO.
                            ;)
                            --
                            Walter Briscoe
                          • Bram Moolenaar
                            ... Right, this was in a previous version. ... Looking at the line again I think this is indeed better. I still don t understand Farsi though... -- Did you
                            Message 13 of 18 , Jul 6, 2005
                            • 0 Attachment
                              Walter Briscoe wrote:

                              > In message <200507060940.j669eiwS058980@...> of Wed, 6 Jul
                              > 2005 11:40:44 in , Bram Moolenaar <Bram@...> writes
                              >
                              > [snip]
                              >
                              > >Right, the ++p doesn't make sense here, since the result of the
                              > >increment doesn't need to be stored. The code isn't written like that,
                              > >the increment is done in a macro. The code did make sense before
                              > >expanding the macro. The macro might be suspicious, but isn't using
                              > >macros anyway?
                              > >
                              >
                              > Bram,
                              > I think you mis-remember.
                              > We have farsi.c(1954): while (((p = vim_strchr(++p, '/')) != NULL) && p[-1] == '\\')
                              > I have main.i(316897): while (((p = vim_strchr(++p, '/')) != ((void *)0)) && p[-1] == '\\')

                              Right, this was in a previous version.

                              > I don't think there is anything unsafe about the code.
                              > There is a sequence point before the call of vim_strchr.
                              > There is another sequence point at && which means that p p[-1] refers to
                              > the result of the assignment rather than the result of the increment.
                              > Appendix C on sequence points in the C99 standard is helpful.
                              >
                              > My proposed fix looks like c**p to me now. Do you agree this is clearer:
                              > while (((p = vim_strchr(p+1, '/')) != NULL) && p[-1] == '\\')

                              Looking at the line again I think this is indeed better. I still don't
                              understand Farsi though...

                              --
                              Did you hear about the new 3 million dollar West Virginia State Lottery?
                              The winner gets 3 dollars a year for a million years.

                              /// Bram Moolenaar -- Bram@... -- http://www.Moolenaar.net \\\
                              /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
                              \\\ Project leader for A-A-P -- http://www.A-A-P.org ///
                              \\\ Buy LOTR 3 and help AIDS victims -- http://ICCF.nl/lotr.html ///
                            Your message has been successfully submitted and would be delivered to recipients shortly.