4

如果我的代码中有这样的内容:

void f(struct foo *x, struct foo *y)
{
  *x = *y; // structure copy (memcpy?)
}

如果 x 和 y 指向同一个地址,会发生什么?

这是有效的代码吗?如果编译器将赋值转换为带有潜在无效操作数的 memcpy 调用(它们不允许重叠)怎么办?

[是的,我知道在这种情况下我可以使用“限制”,但是我们发现的实际代码让我们认为这是由野牛自动生成的,所以我们想知道它是否应该始终有效以及编译器是否应该使用 memmove 或其他允许重叠的东西..]

4

4 回答 4

3

结构分配是完全合法的。因此编译器将生成正确的代码(尽管存在编译器错误)。

于 2011-01-19T12:23:59.043 回答
1

这对我来说看起来完全有效。是的,这将导致一种memcpy.

两个指向structlike 的指针只能相同或根本不重叠。因此,您可以在之前检查指针是否相等。

(你当然可以欺骗你的代码有一个真正的重叠,但这样做必须有一个非常特殊的理由。)

于 2011-01-19T11:03:15.960 回答
0

这是有效的代码。编译器不能假设 x != y,所以它必须使用安全的 memmove。

于 2011-01-19T12:31:26.650 回答
0

[是的,在稍微查看标准并在此处更努力地搜索相关问题后回答我自己的问题]

实际上,这可以通过是否有任何平台在 fd_set 上使用结构副本(对于 select() 或 pselect())导致问题?(在这个答案中),我将在这里粘贴:

应满足下列条件之一:

...

左操作数具有与右操作数兼容的结构或联合类型的限定或非限定版本;

...

如果存储在一个对象中的值是从另一个对象中读取的,该对象以任何方式与第一个对象的存储重叠,那么重叠应该是准确的,并且两个对象应该具有兼容类型的合格或不合格版本;否则,行为未定义。

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

于 2011-01-19T13:18:42.543 回答