a[i] = a[j]... Dangerous?

Discussion in 'C Programming' started by s0suk3@gmail.com, Jul 1, 2008.

  1. Guest

    I'm a bit unclear whether a statement such as 'a = a[j];' causes
    undefined behavior or some other abnormalities. A statement such as
    'a = a[i++];' would definitely cause problems because of the double
    use and side effect of 'i'. But in the former case, will the double
    use of the array 'a' cause problems? Or will the right operand
    ('a[j]') of the assignment be evaluated first and then safely assigned
    to the right operand ('a')?

    Thanks
     
    , Jul 1, 2008
    #1
    1. Advertising

  2. In article <>,
    Kaz Kylheku <> wrote:

    >Note that a = a is well-defined, from which it follows that a = a[j]
    >is well defined even if i == j.


    I don't seem to recall at the moment... if a is an array of
    volatile sig_atomic_t and while the statement a = a; is
    being executed, there is a signal handler fired which changes
    a, what is the "well defined" result?
    --
    "Eightly percent of the people in the world are fools and the
    rest of us are in danger of contamination." -- Walter Matthau
     
    Walter Roberson, Jul 1, 2008
    #2
    1. Advertising

  3. CBFalconer Guest

    wrote:
    >
    > I'm a bit unclear whether a statement such as 'a = a[j];' causes
    > undefined behavior or some other abnormalities. A statement such as
    > 'a = a[i++];' would definitely cause problems because of the
    > double use and side effect of 'i'. But in the former case, will the
    > double use of the array 'a' cause problems? Or will the right
    > operand ('a[j]') of the assignment be evaluated first and then
    > safely assigned to the right operand ('a')?


    Yes. However a pointer to a _may_ be computed before the value
    of a[j] is derived. Your expression is safe.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.
     
    CBFalconer, Jul 1, 2008
    #3
  4. wrote:
    > I'm a bit unclear whether a statement such as 'a = a[j];' causes
    > undefined behavior or some other abnormalities. A statement such as
    > 'a = a[i++];' would definitely cause problems because of the double
    > use and side effect of 'i'. But in the former case, will the double
    > use of the array 'a' cause problems? Or will the right operand
    > ('a[j]') of the assignment be evaluated first and then safely assigned
    > to the right operand ('a')?
    >
    > Thanks


    In the assignment

    a = a[j];

    neither a nor a[j] has any side effects so it is certainly a
    well-defined statement.


    August
     
    August Karlstrom, Jul 1, 2008
    #4
  5. Guest

    On Jul 3, 2:34 am, "Robbie Hatley"
    <> wrote:
    <snip>
    > I use something like the above in production code at work,
    > to periodically move the right-most 80% of an array to the
    > far left, freeing up space on the right. A FIFO buffer;
    > only the most recent data is retained, due to space limitations:
    >
    > int blat[800];
    > ... do some stuff ...
    > // shift data left when buffer gets full:
    > if (BufferIsFull())
    > {
    > for ( i = 0 ; i < 700 ; ++i )
    > {
    > // Discard oldest 100 bytes and shift newest 700 leftward,
    > // freeing 100 bytes on right side of array:
    > blat = blat[i+100];
    > }
    >
    > }


    Just use memmove()

    memmove(blat, &blat[100], 700 * sizeof *blat);
     
    , Jul 3, 2008
    #5
  6. santosh Guest

    Robbie Hatley wrote:

    >
    > <> wrote:
    >
    >> Robbie Hatley wrote:
    >> >
    >> > int blat[800];
    >> > ... do some stuff ...
    >> > // shift data left when buffer gets full:
    >> > if (BufferIsFull())
    >> > {
    >> > for ( i = 0 ; i < 700 ; ++i )
    >> > {
    >> > // Discard oldest 100 bytes and shift newest 700 leftward,
    >> > // freeing 100 bytes on right side of array:
    >> > blat = blat[i+100];
    >> > }
    >> > }

    >>
    >> Just use memmove()
    >> memmove(blat, &blat[100], 700 * sizeof *blat);

    >
    > I'd probably seen "memmove" in the libc header before, but using
    > it for that application simply never occurred to me.
    >
    > And even after reading the instructions for memmove, I like my
    > version better, because it's more obvious what's happening:
    >
    > for ( i = 0; i < 700 ; ++i ) blat = blat[i+1]; // TRANSPARENT
    >
    > Whereas with memmove, you can't "see under the hood":
    >
    > memmove(blat, &blat[100], 700 * sizeof *blat); // OPAQUE
    >
    > I even doubt if the compiled code is faster for memmove.
    > I'd guess it just uses a for loop. And if it does any
    > error checking, it could even be slower. (Though in
    > either case, we're talking maybe about 1 microsecond
    > every 20 minutes or so. Cheap.)


    The standard library memmove can take advantage of any special block
    memory copy instructions that the hardware may have, using assembler.
    Your replacement cannot do so.

    Having said that I have observed in some tests that a custom written
    memmove (also memcpy) is actually faster than the one provided by the
    standard library, if the code is compiled with optimisations enabled.
    This is because the C library on my machine is compiled to run on all
    Intel processors from the 80x386 onwards while my custom memmove is
    optimised for the specific processor model in operation. The difference
    though is minuscule, and shows up only for large copies or intensive
    loops.
     
    santosh, Jul 3, 2008
    #6
  7. Guest

    On Jul 3, 10:37 pm, "Robbie Hatley"
    <> wrote:
    > I'd probably seen "memmove" in the libc header before, but using
    > it for that application simply never occurred to me.
    >
    > And even after reading the instructions for memmove, I like my
    > version better, because it's more obvious what's happening:
    >
    > for ( i = 0; i < 700 ; ++i ) blat = blat[i+1]; // TRANSPARENT
    >
    > Whereas with memmove, you can't "see under the hood":
    >
    > memmove(blat, &blat[100], 700 * sizeof *blat); // OPAQUE
    >
    > I even doubt if the compiled code is faster for memmove.
    > I'd guess it just uses a for loop. And if it does any
    > error checking, it could even be slower. (Though in
    > either case, we're talking maybe about 1 microsecond
    > every 20 minutes or so. Cheap.)

    What other functions of standard C have you replaced with inline code?
    It's bad practise, prone to errors and unproductive.
     
    , Jul 3, 2008
    #7
  8. Guest

    On Jul 4, 1:47 am, "Robbie Hatley"
    <> wrote:
    > "vippstar" wrote:
    > > Robbie Hatley wrote:

    >
    > > > I'd probably seen "memmove" in the libc header before, but using
    > > > it for that application simply never occurred to me.

    >
    > > > And even after reading the instructions for memmove, I like my
    > > > version better, because it's more obvious what's happening:

    >
    > > > for ( i = 0; i < 700 ; ++i ) blat = blat[i+1]; // TRANSPARENT

    >
    > > > Whereas with memmove, you can't "see under the hood":

    >
    > > > memmove(blat, &blat[100], 700 * sizeof *blat); // OPAQUE

    >
    > > > I even doubt if the compiled code is faster for memmove.
    > > > I'd guess it just uses a for loop. And if it does any
    > > > error checking, it could even be slower. (Though in
    > > > either case, we're talking maybe about 1 microsecond
    > > > every 20 minutes or so. Cheap.)

    >
    > > What other functions of standard C have you replaced with inline
    > > code?

    >
    > Misquote. I didn't "replace" memmove with anything. As I said,
    > it never occured to me to use that function (at the time I wrote
    > the program, about 1 year ago). But even if I had known about
    > it at the time, I wouldn't have used it, because the hand-written
    > version is just as short and more transparent.
    >
    > > It's bad practise...

    >
    > Not necessarily. If it's more clear, I'd call it GOOD practice.
    >
    > > ... prone to errors ...

    >
    > Not necessarily. If the hand-written version is simple, it's
    > generally no more "prone to error" than a version using a call
    > to a library function.
    >
    > Specifically, in the "for-loop vs memmove" case you quote,
    > the library function is more error prone, because you have to
    > get three different arguments correct for it to work right.
    >
    > > ... and unproductive ...

    >
    > Nonsense. If it's more clear to the reader, then it's MORE
    > productive, because it takes the reader less time to understand,
    > and REDUCES chance of errors due to reader misunderstanding.
    > (Hint: the reader may be someone other than the original author.)
    >
    > Don't get me wrong, I use std library functions all the time.
    > But if I can do the same thing with a single, simple line of
    > easy-to-understand home-spun code, i'll use the home-spun
    > instead, because it's more TRANSPARENT:

    <snip example>

    This group is for C discussions. Clearly you need to be taught the
    basics of programming, which I don't think I can teach you in a post
    or two. I'll ignore the rest of your replies for this particular
    matter, it's likely that a flame war will come out of it without
    anything important discussed.
     
    , Jul 4, 2008
    #8
  9. Kaz Kylheku Guest

    On 2008-07-03, Robbie Hatley <> wrote:
    >
    > "vippstar" wrote:
    >
    >> Robbie Hatley wrote:
    >>
    >> > I'd probably seen "memmove" in the libc header before, but using
    >> > it for that application simply never occurred to me.
    >> >
    >> > And even after reading the instructions for memmove, I like my
    >> > version better, because it's more obvious what's happening:
    >> >
    >> > for ( i = 0; i < 700 ; ++i ) blat = blat[i+1]; // TRANSPARENT
    >> >
    >> > Whereas with memmove, you can't "see under the hood":
    >> >
    >> > memmove(blat, &blat[100], 700 * sizeof *blat); // OPAQUE
    >> >
    >> > I even doubt if the compiled code is faster for memmove.
    >> > I'd guess it just uses a for loop. And if it does any
    >> > error checking, it could even be slower. (Though in
    >> > either case, we're talking maybe about 1 microsecond
    >> > every 20 minutes or so. Cheap.)

    >>
    >> What other functions of standard C have you replaced with inline
    >> code?

    >
    > Misquote. I didn't "replace" memmove with anything. As I said,
    > it never occured to me to use that function (at the time I wrote
    > the program, about 1 year ago). But even if I had known about
    > it at the time, I wouldn't have used it, because the hand-written
    > version is just as short and more transparent.
    >
    >> It's bad practise...

    >
    > Not necessarily. If it's more clear, I'd call it GOOD practice.
    >
    >> ... prone to errors ...

    >
    > Not necessarily. If the hand-written version is simple, it's
    > generally no more "prone to error" than a version using a call
    > to a library function.
    >
    > Specifically, in the "for-loop vs memmove" case you quote,
    > the library function is more error prone, because you have to
    > get three different arguments correct for it to work right.
    >
    >> ... and unproductive ...

    >
    > Nonsense. If it's more clear to the reader, then it's MORE
    > productive, because it takes the reader less time to understand,
    > and REDUCES chance of errors due to reader misunderstanding.
    > (Hint: the reader may be someone other than the original author.)
    >
    > Don't get me wrong, I use std library functions all the time.
    > But if I can do the same thing with a single, simple line of
    > easy-to-understand home-spun code, i'll use the home-spun
    > instead, because it's more TRANSPARENT:


    Transparency is a desireable property in computer science, when
    it refers to a lack of unwanted interference in data communication,
    or storage access.

    The kind of transparency you are talking about here simply
    refers to an inline expansion of something that is abstract
    to one of its possible implementation.

    All you are doing is burdening the reader with more responsibility.

    > // YES:
    > for ( i = 0; i < 700 ; ++i ) blat = blat[i+1];


    If we include the declaration of i, this is a 19 node
    abstract syntax tree.

    Note that we ca make a small change to the above such that
    its meaning radically changes.

    for ( i = 0; i < 700 ; ++i ) blat += blat[i+1];

    Now it's no longer doing a memmove. So you see the reader has
    to analyze the code carefully; or else such a little
    detail can easily be missed.

    > // NO:
    > memmove(blat, &blat[100], 700 * sizeof *blat);


    This is a 10 node abstract syntax tree. Only 9 if we change
    &blat[100] to blat + 100.

    You're saying it's okay to bloat up code by a factor of 1.9
    to avoid using a library function.

    And that's just the increase in raw synactic complexity.
    There is an increase in semantic complexity also.

    The meaning of the code is ``copy this much data from here
    to there''. The memcpy call simply states that meaning!
    It's a primitive, well-understood operation.

    The expanded algorithm does /not/ just state that meaning;
    the meaning emerges from the relationship of the individual
    steps of the algorithm, as it unfolds in time.

    > I save library functions for things which can NOT be easily
    > handled by hand-written code, such as:
    >
    > // Could do this by hand, but this is MUCH easier:
    > if (strcomp(str1, str2)) {......}


    The function is called strcmp, not strcomp. (Are you sure you use it?)

    The above code can be inlined with a syntactic bloat of over 3.

    This, of course, is worse than 1.9, but not much:

    // 5 node syntax tree

    if (strcmp(s1, s2)) statement;

    // 16 node syntax tree

    while (*s1 && *s2)
    if (*s1++ != *s2++) {
    statement;
    break;
    }

    The professional programmer won't tolerate any increase in syntactic
    complexity for the sake of avoiding the use of a standard library function.
    The exception would be when he is optimizing.
     
    Kaz Kylheku, Jul 6, 2008
    #9
  10. Willem Guest

    Kaz Kylheku wrote:
    ) The function is called strcmp, not strcomp. (Are you sure you use it?)

    Perhaps he's speaking of some non-standard function that compares
    case-insensitively (similar to the also non-standard strcasecmp)

    ) The professional programmer won't tolerate any increase in syntactic
    ) complexity for the sake of avoiding the use of a standard library function.
    ) The exception would be when he is optimizing.

    In which case he should (IMO) keep the library function call that he's
    replacing in a comment.


    SaSW, Willem
    --
    Disclaimer: I am in no way responsible for any of the statements
    made in the above text. For all I know I might be
    drugged or something..
    No I'm not paranoid. You all think I'm paranoid, don't you !
    #EOT
     
    Willem, Jul 7, 2008
    #10
  11. "Robbie Hatley" <> writes:

    > "Willem" <> wrote:
    >
    >> ... he [Robbie Hatley] should (IMO) keep the library function
    >> call that he's replacing in a comment....

    >
    > Misquote. I never replaced any library function call. I wrote
    > the code in question from scratch, electing not to use any
    > library function calls.


    I did not read it as you have edited it. The exchange was:

    | ) The professional programmer won't tolerate any increase in syntactic
    | ) complexity for the sake of avoiding the use of a standard library function.
    | ) The exception would be when he is optimizing.
    |
    | In which case he should (IMO) keep the library function call that he's
    | replacing in a comment.

    To me, the "he" refers to "the professional programmer" not to you in
    person as your edit of the quote seems to suggest. The discussion had
    drifted into a general exchange about what to do ("keep the original")
    in the (now hypothetical) case where one *has* replaced a library
    call. At any rate, when I read the message you replied to, I did not
    read it a referring to your code anymore.

    --
    Ben.
     
    Ben Bacarisse, Jul 8, 2008
    #11
  12. jacob navia Guest

    Mark McIntyre wrote:
    [big snip]
    >
    > But surely you must agree that
    > memmove(a,b);
    > is quicker and clearer to read than 100 lines of hand-crafted code.
    >


    It is quicker and clearer but also completely wrong.

    The prototype for memmove is:
    void * memmove(void *, const void *, size_t);

    You missed the size_t argument.

    Should I deduce that writing library functions is as error prone
    as inlining the code?

    :)

    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
     
    jacob navia, Jul 8, 2008
    #12
  13. Kaz Kylheku Guest

    On 2008-07-04, Kaz Kylheku <> wrote:
    > On 2008-07-03, Robbie Hatley <> wrote:
    >> Specifically, in the "for-loop vs memmove" case you quote,
    >> the library function is more error prone, because you have to
    >> get three different arguments correct for it to work right.

    >
    > All three arguments are also present in the inline code.


    Wow, Friday article appears out of Teranews black hole the following Wednesday!

    Strangly, it's still not visible on their server!
     
    Kaz Kylheku, Jul 9, 2008
    #13
  14. CBFalconer Guest

    Kaz Kylheku wrote:
    > Kaz Kylheku <> wrote:
    >> Robbie Hatley <> wrote:
    >>
    >>> Specifically, in the "for-loop vs memmove" case you quote,
    >>> the library function is more error prone, because you have to
    >>> get three different arguments correct for it to work right.

    >>
    >> All three arguments are also present in the inline code.

    >
    > Wow, Friday article appears out of Teranews black hole the
    > following Wednesday!
    >
    > Strangly, it's still not visible on their server!


    Teranews has that habit. It appears about every two weeks or so.
    Then they propagate the whole schmeer after a three to five day
    delay. Recently they had even more failings, so I switched to
    motzarella, and all seems fine so far. When I first used Teranews
    they didn't have that delay problem.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.
     
    CBFalconer, Jul 9, 2008
    #14
  15. CBFalconer Guest

    CBFalconer wrote:
    > Kaz Kylheku wrote:
    >> Kaz Kylheku <> wrote:
    >>> Robbie Hatley <> wrote:
    >>>
    >>>> Specifically, in the "for-loop vs memmove" case you quote,
    >>>> the library function is more error prone, because you have to
    >>>> get three different arguments correct for it to work right.
    >>>
    >>> All three arguments are also present in the inline code.

    >>
    >> Wow, Friday article appears out of Teranews black hole the
    >> following Wednesday!
    >>
    >> Strangly, it's still not visible on their server!

    >
    > Teranews has that habit. It appears about every two weeks or so.
    > Then they propagate the whole schmeer after a three to five day
    > delay. Recently they had even more failings, so I switched to
    > motzarella, and all seems fine so far. When I first used
    > Teranews they didn't have that delay problem.


    PS: Teranews has also taken to stealing the Organization slot in
    the headers. A further nuisance.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.
     
    CBFalconer, Jul 10, 2008
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alex Munk

    A potentially dangerous Request.Form

    Alex Munk, Dec 16, 2003, in forum: ASP .Net
    Replies:
    2
    Views:
    595
    Adrijan Josic
    Dec 17, 2003
  2. Anil Kripalani
    Replies:
    2
    Views:
    494
    Eric Lawrence [MSFT]
    Feb 25, 2004
  3. amit
    Replies:
    1
    Views:
    521
    Eric Lawrence [MSFT]
    Feb 26, 2004
  4. cesark
    Replies:
    2
    Views:
    2,649
  5. Boris
    Replies:
    5
    Views:
    2,539
    Joe Kaplan \(MVP - ADSI\)
    Apr 17, 2004
Loading...

Share This Page