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

Re: Mainly noise

Expand Messages
  • Bram Moolenaar
    ... The NULL argument isn t used, because another argument has a specific value that is checked in an if . That s nearly impossible to find in static checks:
    Message 1 of 18 , Jul 4, 2005
    • 0 Attachment
      James Widman wrote:

      > > 2) --- Module: ex_getln.c
      > >
      > > During Specific Walk:
      > > File ex_getln.c line 2968: ExpandOne(?, 0, 0, 0, 5?)
      > > File ex_getln.c line 3149: ExpandFromContext(?, 0, [1], [1], 0)
      > > File ex_getln.c line 4029: ExpandRTDir(0, [1], [1], !=0)
      > > ex_getln.c(4286) : Warning 418: Passing null pointer to function
      > > 'strlen(const char *)', arg. no. 1 [Reference: file ex_getln.c:
      > > lines 2968,
      > > 3148, 4029]
      > >
      > > PC-lint value-tracking is insufficiently sophisticated. There are
      > > several such spurious diagnostics.
      >
      > At first blush this certainly seems spurious. Walter, can you send
      > me your lint configuration for vim7 (and the preprocessor output for
      > that module)? I'd like to reproduce this.

      The NULL argument isn't used, because another argument has a specific
      value that is checked in an "if". That's nearly impossible to find in
      static checks: The "mode" argument is passed the value of the "type"
      variable, which was set to WILD_NEXT or WILD_PREV earlier. Stil, a
      human can figure this out, thus a program might be able to see it too.

      > > 5) --- Module: gui_w32.c
      > > add_long(lStyle);
      > > #... *((LPDWORD)p)++ = (lStyle)
      > > ^
      > > gui_w32.c(2875) : Error 52: Expected an lvalue
      > >
      > > A cast loses lvalueness in C
      >
      > Right...
      >
      > > ...while retaining it in C++
      >
      > Quoth ISO C++ section 5.4,p1:
      > "The result of the expression(T)cast-expression is of type T. The
      > result is an lvalue if T is a reference
      > type, otherwise the result is an rvalue."
      >
      > > I don't have a fix I like for this and similarly-featured macros.
      >
      > Ditto. I'd like to see the fix if/when someone comes up with one.
      > I'm not sure that this diagnostic points to a bug that would result
      > in Bad Things Happening(TM), but it's definitely a non-portable
      > construct. The Comeau compiler is one that issues an error when it
      > sees code like this.

      I think nearly all C compilers can handle this, since in practice it's
      just incrementing a pointer by the size of what it points to. In some C
      standards it might be "undefined" though.

      Problem is that there is no good workaround to avoid the warning message.

      --
      hundred-and-one symptoms of being an internet addict:
      223. You set up a web-cam as your home's security 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 ///
    • 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 2 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 3 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 4 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 5 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 6 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 7 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 8 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 9 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 10 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 11 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 12 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 13 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 14 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.