Q:

What's the fastest way to copy two adjacent bytes in C?

Ok so let's start with the most obvious solution:
memcpy(Ptr, (const char[]){'a', 'b'}, 2);

There's quite an overhead of calling a library function. Compilers sometimes don't optimize it, well I wouldn't rely on compiler optimizations but even though GCC is smart, if I'm porting a program to more exotic platforms with trashy compilers I don't want to rely on it.
So now there's a more direct approach:
Ptr[0] = 'a';
Ptr[1] = 'b';

It doesn't involve any overhead of library functions, but is making two different assignments. Third we have a type pun:
*(uint16_t*)Ptr = *(uint16_t*)(unsigned char[]){'a', 'b'};

Which one should I use if in a bottleneck? What's the fastest way to copy only two bytes in C?
Regards,
Hank Sauri

A:

Only two of the approaches you suggested are correct:
memcpy(Ptr, (const char[]){'a', 'b'}, 2);

and
Ptr[0] = 'a';
Ptr[1] = 'b';

On X86 GCC 10.2, both compile to identical code:
mov     eax, 25185
mov     WORD PTR [something], ax

This is possible because of the as-if rule.
Since a good compiler could figure out that these are identical, use the one that is easier to write in your cse. If you're setting one or two bytes, use the latter, if several use the former or use a string instead of a compound literal array.

The third one you suggested
*(uint16_t*)Ptr = *(uint16_t*)(unsigned char[]){'a', 'b'};

also compiles to the same code when using x86-64 GCC 10.2, i.e. it would behave identically in this case.
But in addition it has 2-4 points of undefined behaviour, because it has twice strict aliasing violation and twice, coupled with possible unaligned memory access at both source and destination. Undefined behaviour does not mean that it must not work like you intended, but neither does it mean that it has to work as you intended. The behaviour is undefined. And it can fail to work on any processor, including x86. Why would you care about the performance on a bad compiler so much that you would write code that would fail to work on a good compiler?!

A:

When in doubt, use the Compiler Explorer.
#include <string.h>
#include <stdint.h>

int c1(char *Ptr) {
    memcpy(Ptr, (const char[]){'a', 'b'}, 2);
}

int c2(char *Ptr) {
    Ptr[0] = 'a';
    Ptr[1] = 'b';
}

int c3(char *Ptr) {
    // Bad bad not good.
    *(uint16_t*)Ptr = *(uint16_t*)(unsigned char[]){'a', 'b'};
}

compiles down to (GCC)
c1:
        mov     eax, 25185
        mov     WORD PTR [rdi], ax
        ret
c2:
        mov     eax, 25185
        mov     WORD PTR [rdi], ax
        ret
c3:
        mov     eax, 25185
        mov     WORD PTR [rdi], ax
        ret

or (Clang)
c1:                                     # @c1
        mov     word ptr [rdi], 25185
        ret
c2:                                     # @c2
        mov     word ptr [rdi], 25185
        ret
c3:                                     # @c3
        mov     word ptr [rdi], 25185
        ret

