Is it technically impossible to implement memcpy from scratch in Standard C?

前端 未结 2 593
独厮守ぢ
独厮守ぢ 2021-02-19 17:23

Howard Chu writes:

In the latest C spec it is impossible to write a \"legal\" implementation of malloc or memcpy.

Is this right? My

2条回答
  •  执念已碎
    2021-02-19 17:47

    TL;DR
    It should be fine, as long as the memcpy is based on naive character-by-character copy.

    And not optimized to move chunks of the size of the largest aligned type that can be copied in a single instruction. The latter is how standard lib implementations do it.


    What's concerning is something like this scenario:

    void* my_int = malloc(sizeof *my_int);
    int another_int = 1;
    
    my_memcpy(my_int, &another_int, sizeof(int));
    
    printf("%d", *(int*)my_int); // well-defined or strict aliasing violation?
    

    Explanation:

    • The data pointed at my my_int has no effective type.
    • When we copy the data into the my_int location, one might be concerned that we force the effective type to become unsigned char, since that's what my_memcpy uses.
    • And then when we read that memory location through int*. Would we violate strict aliasing?

    However, the key here is a special exception in the rule for effective type, specified in C17 6.5/6, emphasis mine:

    If a value is copied into an object having no declared type using memcpy or memmove, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one.

    Since we do copy the array as character type, the effective type of what my_int points at will become that of the object another_int from which the value was copied.

    So everything should be fine.

    In addition, you restrict-qualified the parameters so there should be no fuss regarding if the two pointers might alias each other, just like real memcpy.

    Notably, this rule has remained the same through C99, C11 and C17. One might argue that it is a very bad rule abused by compiler vendors, but that's another story.

提交回复
热议问题