C structure assignment of same address valid?
If I have something like this in my code:
void f(struct foo *x, struct foo *y)
{
*x = *y; // structure copy (memcpy?)
}
If x and y point to the same address, what happens?
Is this valid code, and what if the compiler converts the assignment into a memcpy call with potentially-invalid operands (they aren't allowed to overlap)?
[Yes, I know I can use "restrict" in this case, but the actual code we found which made us consider this is automa开发者_运维知识库tically-generated by bison so we were wondering if it should always be valid and whether the compiler should use memmove or something else which allows overlap..]
Structure assignment is perfectly legal. Therefore the compiler will generate the correct code (compiler bugs notwithstanding).
This looks perfectly valid to me. Yes, this will result in a sort of memcpy
.
Two pointers to struct
like that should only either be the same or not overlap at all. So you could do a check if the pointers are equal, before.
(You can certainly trick your code to have a real overlap, but there'd have to be a really special reason to do that.)
This is valid code. The compiler can not assume x != y, so it must use safe memmove.
[Yes, answering my own question as I saw this after looking in the standard a bit and searching harder for related questions on here]
Actually, this is answered by part of the answer to Are there any platforms where using structure copy on an fd_set (for select() or pselect()) causes problems? (in this answer), which I will paste here:
One of the following shall hold:
...
the left operand has a qualified or unqualified version of a structure or union type compatible with the type of the right;
...
If the value being stored in an object is read from another object that overlaps in any way the storage of the first object, then the overlap shall be exact and the two objects shall have qualified or unqualified versions of a compatible type; otherwise, the behavior is undefined.
Hence as long as the pointers are the same (i.e. total overlap) then this is fine. Still seems odd that the compiler inserts a call to memcpy sometimes for this despite the spec of memcpy saying that overlap is not allowed. Perhaps the compiler knows more about the particular implementation of memcpy than the documentation eludes to..
精彩评论