David Gardner
David Gardner

Reputation: 7903

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 automatically-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..]

Upvotes: 4

Views: 508

Answers (4)

David Gardner
David Gardner

Reputation: 7903

[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..

Upvotes: 0

unsigned
unsigned

Reputation: 1

This is valid code. The compiler can not assume x != y, so it must use safe memmove.

Upvotes: 0

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272677

Structure assignment is perfectly legal. Therefore the compiler will generate the correct code (compiler bugs notwithstanding).

Upvotes: 3

Jens Gustedt
Jens Gustedt

Reputation: 78953

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.)

Upvotes: 1

Related Questions