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

JohnF (archive)

Usenet Archive
Joined
Aug 14, 2006
Messages
164
Reaction score
0
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,
 

Noob (archive)

Usenet Archive
Joined
Aug 13, 2009
Messages
450
Reaction score
0
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.
 

JohnF (archive)

Usenet Archive
Joined
Aug 14, 2006
Messages
164
Reaction score
0
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))
 

christian.bau

Usenet Archive
Joined
Dec 3, 2006
Messages
510
Reaction score
0
On Feb 17, 8:44 am, JohnF wrote:
Noob wrote:
> Noob wrote:
>> JohnF wrote:
>>> 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.
...

That's totally wrong. Check it with n = 2, and an array containing the chars 'x', 0, 'y', 0. After calling strcpy (s, s+2) the array would be 'y', 0, 'y', 0.

Use memmove (s, s + n, strlen (s + n) + 1) instead.
 

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
548,042
Messages
3,104,223
Members
248,131
Latest member
Tonypshaw1

Latest Threads

Top