possibly undefined operation

L

luser- -droog

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
 
I

Ike Naar

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;
}
 
L

luser- -droog

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.
 
I

Ike Naar

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.
 
L

luser- -droog

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++;
}
 
I

Ike Naar

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);
 
J

John Bode

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.
 
S

Seebs

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
 
J

Jorgen Grahn

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
 
I

Ike Naar

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).
 
J

Jorgen Grahn

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top