cpointersconstantsfunction-declarationqualifiers

Why this code works ? memcpy on a constant array


The parameters for memcpy are memcpy(void *_Dst, const void *_Src, size_t _Size)

But with the following code, I pass a constant array as parameter '_Src' and it still copy the content of the array into the destination, even though I didn't pass a const void *.

int tab[3] = { 1, 2, 3 };
    
memcpy(tab, (int[3]) { 7, 8, 9 }, sizeof(int) * 3);
    
printf("%d %d %d \n", tab[0], tab[1], tab[2]); // Output: 7 8 9

Does the expression (int[3]) { 7, 8, 9 } returns a pointer to the first element of the array?


Solution

  • This

    (int[3]) { 7, 8, 9 }
    

    is a compound literal of the type int[3] that used as a function argument is implicitly converted to a pointer to its first element.

    On the other hand (The C Standard, 6.3.2.3 Pointers)

    1 A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

    and

    2 For any qualifier q, a pointer to a non-q-qualified type may be converted to a pointer to the q-qualified version of the type; the values stored in the original and converted pointers shall compare equal.

    So in this call

    memcpy(tab, (int[3]) { 7, 8, 9 }, sizeof(int) * 3);
    

    the compound literal is converted at first to a pointer of the type int * to its first element that then is converted to the type void * according to the first quote and then to the type const void * according to the second quote.

    The qualifier const means that the pointed object will not be changed within the function. It does not mean that the expression used as an argument is a constant expression.