3

First hit for memcpy source code c. The implementation is a while loop that copies one byte at a time. Though many answers make it clear that the actual implementation is a lot faster than copying one byte at a time. Where can I find the real implementation, the real, heavily optimized one that the compiler actually uses? What does it look like in C?

Seeking recommendations for books, tools, software libraries, and more

Not really. I am asking how an existing implementation works, not which library etc. I should use.

2 Answers2

2

It is not the job of the compiler to define a C library. C library functions are the responsibility of the C library. For example gcc is responsible for things like soft float functions so that the language can be completely implemented for a particular target. The core stdint.h functions as the compiler defines the sizes for the language specific variable types (char, short, int, etc) and stdint.h is derived from that so only the compiler can define those.

But C library items, the bootstrap, linker script, and all C library functions, printf(), memcpy(), etc. And since at least in the gnu world the compiler, assembler/linker, C library, etc are separate items, you can for example mix gcc, binutils and glibc or you can instead use gcc, binutils, and newlib. And there is no reason to expect glibc and newlib or any other C library to have the same memcpy implementation.

Other toolchains and libraries may be integrated.

Of course you could just compile in a simple test program with one line memcpy(...) and disassemble it.

memcpy is a special deal in that some compilers will generate a memcpy and at times may also the other way remove the memcpy and replace it with a few instructions.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
unsigned int fun ( unsigned int *x )
{
    unsigned int y;
    memcpy(&y,x,sizeof(unsigned int));
    return(y);
}

Disassembly of section .text:

0000000000000000 <fun>:
   0:   8b 07                   mov    (%rdi),%eax
   2:   c3                      retq 


typedef struct
{
    unsigned int ui[37];
    unsigned short us[33];
    unsigned char uc[31];
} HELLO;
HELLO one;
void fun ( HELLO two )
{
    one=two;
}

00000000 <fun>:
   0:   e24dd010    sub sp, sp, #16
   4:   e92d4010    push    {r4, lr}
   8:   e28dc008    add ip, sp, #8
   c:   e88c000f    stm ip, {r0, r1, r2, r3}
  10:   e1a0100c    mov r1, ip
  14:   e3a020f8    mov r2, #248    ; 0xf8
  18:   e59f000c    ldr r0, [pc, #12]   ; 2c <fun+0x2c>
  1c:   ebfffffe    bl  0 <memcpy>
  20:   e8bd4010    pop {r4, lr}
  24:   e28dd010    add sp, sp, #16
  28:   e12fff1e    bx  lr
  2c:   00000000    .word   0x00000000

And some compilers will have an option to request/require that they don't insert memcpy's or other library functions you didn't ask for.

If the memcpy survives to link time then whatever the linker is told to link is what gets linked.

halfer
  • 19,824
  • 17
  • 99
  • 186
old_timer
  • 69,149
  • 8
  • 89
  • 168
2

Where can I find the real implementation, the real,

The word "real" doesn't make sense here. Everything is "real".

heavily optimized

The word "heavily" is subjective.

one that the compiler actually uses?

The compiler may optimize memcpy out in different ways, as long as side-effects stay the same. So I guess that would make two implementation available, so a compiler may have an internal like "compile-time" memcpy implementation, and C standard library may provide a separate memcpy implementation.

What does it look like in C?

There are many available implementations of C standard library and each one of them has it's own implementation of memcpy, even each one of them may have (and has) different implementation of memcpy for different architectures. For optimizations purposes some C standard library implementations sometimes choose implement memcpy in assembly for specific architectures. You can find for example newlibs generic memcpy or newlib's memcpy for arm in assembly or glibc generic memcpy and glibc i386 memcpy implementation.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111