strcpy(s,s+n) versus memmove, redux

J

JohnF

A while back (in a thread I'm no longer seeing on my newsreader)
you all convinced me strcpy(s,s+n) is a really bad idea, and
I indeed changed code accordingly. Of course, I was always aware
it's formally wrong, but also aware it usually works just fine.
Unfortunately, some unchanged code (I couldn't go back and change
every last program) just popped that cork -- a user emailed me
a bug that showed up when he recompiled on Centos 6, whereas
it had worked fine on 5.4. I tracked the bug down to this kind of
strcpy() and fixed it with an equivalent memmove().
Okay, fine. But now I'm re-wondering what's going on.
As a former IBM bal assembly programmer, and also Data General
assembly programmer, I can't think of any multiple byte block move
type of instruction that operates in an out-of-address order.
So what is a compiler/optimizer "thinking" that leads it to
generate machine code that operates in some out-of-address order
in this kind of situation? Got an example where it actually
makes any sense to do things that way? Thanks,
 
N

Noob

JohnF said:
A while back (in a thread I'm no longer seeing on my newsreader)
you all convinced me strcpy(s,s+n) is a really bad idea, and
I indeed changed code accordingly. Of course, I was always aware
it's formally wrong, but also aware it usually works just fine.
Unfortunately, some unchanged code (I couldn't go back and change
every last program) just popped that cork -- a user emailed me
a bug that showed up when he recompiled on Centos 6, whereas
it had worked fine on 5.4. I tracked the bug down to this kind of
strcpy() and fixed it with an equivalent memmove().
Okay, fine. But now I'm re-wondering what's going on.
As a former IBM bal assembly programmer, and also Data General
assembly programmer, I can't think of any multiple byte block move
type of instruction that operates in an out-of-address order.
So what is a compiler/optimizer "thinking" that leads it to
generate machine code that operates in some out-of-address order
in this kind of situation? Got an example where it actually
makes any sense to do things that way? Thanks,

There was a similar issue when Intel optimized memcpy.

http://lwn.net/Articles/414467/

cf. the actual patch set:
http://article.gmane.org/gmane.comp.lib.glibc.alpha/15278

Regards.
 
J

JohnF

Noob said:
See also the discussion in this bug report.
http://sourceware.org/bugzilla/show_bug.cgi?id=12518

Thanks for the info. 414467 does mention "more highly optimized
for current processors", and I guess careful study of the patch
at 15278 would reveal exactly how (at least for Atom), but I'm
way too lazy to go that far. I like 12518's suggestion of aliasing
memmove to memcpy, although my lazy use of strcpy(s,s+n) was just
to avoid that pesky third arg. So I've now introduced the
following macro into all my code, though there's still a lot
of old code that remains to be retrofitted,
/* --- strcpy(s,s+n) using memmove() (also works for negative n) --- */
#define strsqueeze(s,n) if((n)!=0) { if(!isempty((s))) { \
int thislen=strlen(s); \
if ((n) >= thislen) *(s) = '\000'; \
else memmove((s),(s)+(n),1+thislen-(n)); }} else/*user adds final;*/
where
/* --- check if a string is empty --- */
#define isempty(s) ((s)==NULL?1:(*(s)=='\000'?1:0))
 

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,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top