0

Is this method of copying a string faster than copying each char individually? The idea of this code is that it could (but I am not sure if it is so) be faster to copy 8 bytes at once instead of a single byte. It is very un-safe but it seems to work somehow. Or it's just a bad idea?

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

void* copy_string(char s[])
{
    int len=strlen(s);
    int i=0;

    double *p=(double*)s;
    double *copy=(double*)malloc(len+1);

    while(i-len>8)
    {
         *copy=*(p++);
         copy++;
         i+=8;
    }
    char *p2=(char*)p;
    char *c=(char*)copy;
    while(i<len)
    {
         *c=*(p2++);
         c++;
         i++;
    }
    *c='\0';
    return copy;
}

int main()
{
    char s[]="GOODBYE SAFE WORLD!";
    char *c=copy_string(s);
    printf("%s",c);
    return 0;
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
  • 1
    Why not just memcpy it? Trying to loop unroll a byte by byte copy seems kinda pointless; though for giggles you could look up Duffs Device... – Joe Dec 17 '15 at 13:37
  • It is just curiosity. –  Dec 17 '15 at 13:38
  • Why not benchmarking it? – bznein Dec 17 '15 at 13:47
  • It may or may not be faster, but it would definitely violate strict aliasing and is therefore likely to fail, especially in this example on architectures that place alignment restrictions on `double` variables. See http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule – Andrew Henle Dec 17 '15 at 14:01
  • you are right. i-len does nothing –  Dec 17 '15 at 14:03
  • 1
    @AndrewHenle, this has nothing to do with strict aliasing. Assuming that the condition of the first `while` loop is fixed, the rules for pointer conversions are violated: *A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined.* On many architectures this will simply result in a "bus error". – Jens Gustedt Dec 17 '15 at 14:11

1 Answers1

3

Tricks like that may be faster under some circumstances on some architectures. Trust your provider of your C library to know about these tricks if they apply.

In your case, your code is simply wrong. Assuming that the condition of the first while loop is fixed, the rules for pointer conversions are violated:

A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behavior is undefined.

On many architectures this will simply result in a "bus error".

To see how these kind of tricks work, check out the sources of your favorite C library and look for their implementation of memcpy and memmove.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177