Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is strcpy implemented?

Tags:

c

strcpy

I have a question about using strcpy. I know the ANSI C standard says : source and destination must not overlap, otherwise the behaviour is unpredictable. I show you a piece of code that works as I expect if it is compiled using an old gnu C compiler under Linux.

#include <string.h>
#include <stdio.h>

char S[80],*P;

int main() {
    strcpy(S,"abcdefghi\r\njklmnopqr\r\nstuvwxyz\r\n");
    for (P=S; P=strchr(P,'\r'); P++) strcpy(P,P+1);
    printf("%s\n",S);
    return 0;
}

This sequence removes every \r (carriage return) from the input string. I know (from Kernigham and Ritchie) that a very simple implementation for strcpy is the following

while (*t++=*s++) ;

Now I compiled my program using gcc (Gentoo 4.5.4 p1.0, pie-0.4.7) 4.5.4 and it prints this:

abcdefghi
jklmnpqr          <-- missing 'o'
stuvwxxyz         <-- doubled 'x'

I suppose this compiler (in fact its library) uses a very sophisticated sequence for strcpy, and I don't understand the reason.

like image 995
Nelu Cozac Avatar asked Oct 17 '12 13:10

Nelu Cozac


1 Answers

You were warned not to do that. The reason is that a byte-for-byte copy is actually quite slow and requires a lot of looping to get through a string. The compiler can optimize this easily (for instance, by copying an int-sized chunk at a time, or using some platform-specific parallellization.)

But if the strings overlap, then those optimizations make assumptions about your data that are no longer valid. As a result, they give you unspecified results. It is likely your older GCC simply didn't do any such optimizations.

Since the documentation for strcpy() says not to use overlapping strings, don't.

like image 95
Jonathan Grynspan Avatar answered Oct 13 '22 00:10

Jonathan Grynspan