possibly undefined operation

Discussion in 'C Programming' started by luser- -droog, Dec 30, 2010.

  1. How worried shoud I be about this warning?
    It's only modified once, right?

    cat tos.c && make tos
    #include <stdio.h>

    int main(void) {
    /* stack */
    char stac[100];
    char *tos = stac;

    /* string */
    char *str = "a string";
    char *s;

    /* push some elements */
    for (s = str; *s; s++)
    *tos++ = *s;

    /* copy elements */
    {
    int n = tos-stac;
    *tos++ = tos[-n]; /* undefined? */
    }

    *tos++ = 0;
    puts(stac);
    return 0;
    }
    /* eof */
    cc -g -Wall tos.c -o tos
    tos.c: In function 'main':
    tos.c:19: warning: operation on 'tos' may be undefined
     
    luser- -droog, Dec 30, 2010
    #1
    1. Advertising

  2. luser- -droog

    Ike Naar Guest

    On 2010-12-30, luser- -droog <> wrote:
    > How worried shoud I be about this warning?
    > {
    > int n = tos-stac;
    > *tos++ = tos[-n]; /* undefined? */ [line 19]
    > }
    > tos.c:19: warning: operation on 'tos' may be undefined


    The behaviour is undefined (tos is inspected on the right hand side
    of the assignment operator, and modified on the left hand side of the
    assignment operator, with no intervening sequence point).

    Did you indend to do this:

    {
    *tos++ = *stac;
    }
     
    Ike Naar, Dec 30, 2010
    #2
    1. Advertising

  3. luser- -droog

    Ike Naar Guest

    On 2010-12-30, Ike Naar <> wrote:
    > Did you indend to do this:


    I meant 'intend' ;-)
     
    Ike Naar, Dec 30, 2010
    #3
  4. On Dec 30, 3:33 am, Ike Naar <> wrote:
    > On 2010-12-30, luser- -droog <> wrote:
    >
    > > How worried shoud I be about this warning?
    > >     {
    > >         int n = tos-stac;
    > >         *tos++ = tos[-n]; /* undefined? */   [line 19]
    > >     }
    > > tos.c:19: warning: operation on 'tos' may be undefined

    >
    > The behaviour is undefined (tos is inspected on the right hand side
    > of the assignment operator, and modified on the left hand side of the
    > assignment operator, with no intervening sequence point).
    >
    > Did you intend to do this:
    >
    >     {
    >         *tos++ = *stac;
    >     }


    I meant to do a little loop. Pushing the stack
    with elements from the stack at a fixed offset
    from the top.

    /* copy elements */
    {
    int i,n;
    i = n = tos-stac;
    while (i--)
    *tos++ = tos[-n]; /* undefined? */
    }

    It appears to execute fine. Even at -O3.
     
    luser- -droog, Dec 30, 2010
    #4
  5. luser- -droog

    Ike Naar Guest

    On 2010-12-30, luser- -droog <> wrote:
    > I meant to do a little loop. Pushing the stack
    > with elements from the stack at a fixed offset
    > from the top.
    >
    > /* copy elements */
    > {
    > int i,n;
    > i = n = tos-stac;
    > while (i--)
    > *tos++ = tos[-n]; /* undefined? */
    > }
    >
    > It appears to execute fine. Even at -O3.


    "Appears to execute fine" is one possible manifestation of undefined
    behaviour.
     
    Ike Naar, Dec 30, 2010
    #5
  6. On Dec 30, 2:46 am, luser- -droog <> wrote:
    > How worried shoud I be about this warning?
    > It's only modified once, right?


    Rewriting with a pointer makes it all better.

    > cat tos.c && make tos
    > #include <stdio.h>
    >
    > int main(void) {
    >     /* stack */
    >     char stac[100];
    >     char *tos = stac;
    >
    >     /* string */
    >     char *str = "a string";
    >     char *s;
    >
    >     /* push some elements */
    >     for (s = str; *s; s++)
    >         *tos++ = *s;
    >
    >     /* copy elements */
    >     {
    >         int i,n;
    > i = n = tos-stac;
    > while (i--)
    >         *tos++ = tos[-n]; /* undefined? */
    >     }


    /* copy elements */
    {
    int n;
    char *t;
    n = tos-stac;
    t = stac;
    while (n--)
    *tos++ = *t++;
    }


    >     *tos++ = 0;
    >     puts(stac);
    >     return 0;}
    >
    > /* eof */
    > cc -g -Wall    tos.c   -o tos
    > tos.c: In function 'main':
    > tos.c:19: warning: operation on 'tos' may be undefined
     
    luser- -droog, Dec 30, 2010
    #6
  7. luser- -droog

    Ike Naar Guest

    On 2010-12-30, luser- -droog <> wrote:
    > Rewriting with a pointer makes it all better.


    Yes.

    > /* copy elements */
    > {
    > int n;
    > char *t;
    > n = tos-stac;
    > t = stac;
    > while (n--)
    > *tos++ = *t++;
    > }


    Why not use memcpy from <string.h>, and replace the whole thing by

    memcpy(tos, stac, tos-stac);
     
    Ike Naar, Dec 30, 2010
    #7
  8. luser- -droog

    John Bode Guest

    On Dec 30, 5:30 am, "christian.bau" <>
    wrote:
    > On Dec 30, 10:25 am, Ike Naar <> wrote:
    >
    > > "Appears to execute fine" is one possible manifestation of undefined
    > > behaviour.

    >
    > And "Appears to execute fine in development, but breaks when the
    > application is shipped to a customer" is another possible
    > manifestation :)


    That's the *most common* manifestation in my experience.
     
    John Bode, Dec 30, 2010
    #8
  9. On Dec 30, 10:41 am, Ike Naar <> wrote:
    > On 2010-12-30, luser- -droog <> wrote:
    >
    > > Rewriting with a pointer makes it all better.

    >
    > Yes.
    >
    > >     /* copy elements */
    > >     {
    > >         int n;
    > >         char *t;
    > >         n = tos-stac;
    > >         t = stac;
    > >         while (n--)
    > >             *tos++ = *t++;
    > >     }

    >
    > Why not use memcpy from <string.h>, and replace the whole thing by
    >
    >     memcpy(tos, stac, tos-stac);


    Oh, I hadn't thought of that. *poof*
     
    luser- -droog, Dec 30, 2010
    #9
  10. luser- -droog

    Seebs Guest

    On 2010-12-30, luser- -droog <> wrote:
    > How worried shoud I be about this warning?


    You should fix the code.

    > It's only modified once, right?


    So what?

    > *tos++ = tos[-n]; /* undefined? */


    Yes, undefined. Even if it weren't "undefined", you would have no
    information as to whether tos[-n] was indexing from the previous
    or new value of tos. But it's undefined, so it's also allowed to
    index into a half-loaded pointer which has garbage bits in its top
    half, or something like that. In short, it's nonsense. Don't do that.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    I am not speaking for my employer, although they do rent some of my opinions.
     
    Seebs, Dec 30, 2010
    #10
  11. luser- -droog

    Jorgen Grahn Guest

    On Thu, 2010-12-30, Ike Naar wrote:
    > On 2010-12-30, luser- -droog <> wrote:
    >> Rewriting with a pointer makes it all better.

    >
    > Yes.
    >
    >> /* copy elements */
    >> {
    >> int n;
    >> char *t;
    >> n = tos-stac;
    >> t = stac;
    >> while (n--)
    >> *tos++ = *t++;
    >> }

    >
    > Why not use memcpy from <string.h>, and replace the whole thing by
    >
    > memcpy(tos, stac, tos-stac);


    I'm too lazy to read the whole original code, but remember that with
    memcpy() the source and destination regions may not overlap.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Dec 31, 2010
    #11
  12. luser- -droog

    Ike Naar Guest

    On 2010-12-31, Jorgen Grahn <> wrote:
    > On Thu, 2010-12-30, Ike Naar wrote:
    >> memcpy(tos, stac, tos-stac);

    >
    > I'm too lazy to read the whole original code, but remember that with
    > memcpy() the source and destination regions may not overlap.


    If you're too lazy to read the original code, then it's sufficient
    to look at the mempcy call, from which you can deduce that source
    and destination are adjacent and do not overlap.
    (the operation only makes sense if you assume that stac and tos
    are valid pointers into the same array and stac<=tos; these
    assumptions hold in the original code).
     
    Ike Naar, Dec 31, 2010
    #12
  13. luser- -droog

    Jorgen Grahn Guest

    On Fri, 2010-12-31, Ike Naar wrote:
    > On 2010-12-31, Jorgen Grahn <> wrote:
    >> On Thu, 2010-12-30, Ike Naar wrote:
    >>> memcpy(tos, stac, tos-stac);

    >>
    >> I'm too lazy to read the whole original code, but remember that with
    >> memcpy() the source and destination regions may not overlap.

    >
    > If you're too lazy to read the original code, then it's sufficient
    > to look at the mempcy call, from which you can deduce that source
    > and destination are adjacent and do not overlap.
    > (the operation only makes sense if you assume that stac and tos
    > are valid pointers into the same array and stac<=tos; these
    > assumptions hold in the original code).


    Well, I was too lazy to realize that too, but you're right of course.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Jan 2, 2011
    #13
    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. david ullua
    Replies:
    13
    Views:
    678
  2. raan
    Replies:
    2
    Views:
    457
  3. Mark

    possibly undefined behavior

    Mark, Jun 18, 2009, in forum: C Programming
    Replies:
    44
    Views:
    1,111
    Tim Rentsch
    Jun 22, 2009
  4. Buzz Lightyear
    Replies:
    10
    Views:
    1,139
    Alexander Bartolich
    Aug 12, 2009
  5. Chris Beall

    Reference to possibly undefined variable

    Chris Beall, Mar 1, 2005, in forum: Javascript
    Replies:
    4
    Views:
    152
Loading...

Share This Page