2011-01-19 46 views
4

如果我在我的代码是这样的:相同地址的C结构赋值有效吗?

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

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

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

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

回答

0

[是,回答我的问题,因为我看到这个标准找了一下,对这里的相关问题,搜索困难后]

其实,这是答案的一部分回答到Are there any platforms where using structure copy on an fd_set (for select() or pselect()) causes problems?(在this answer ),我会在这里贴:

下列情况之一的应持有:

...

左操作具有含水与权利类型相符的结构或联合类型的不合格或不合格版本;

...

如果该值被存储在一个对象从以任何方式与第一对象的存储,则该重叠应精确重叠的另一对象读取和两个对象应具有合格或兼容类型的非限定版本;否则,行为是不确定的。

因此,只要指针是相同的(即总重叠),那么这很好。尽管memcpy规范说不允许重叠,但编译器插入对memcpy的调用仍然有点奇怪。也许编译器知道更多关于memcpy的具体实现,而不是文档逃避到...

1

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

像这样的两个指针struct应该只有相同或根本不重叠。所以你可以做一个检查,如果指针是平等的,之前。

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

+0

有没有必要做一个检查。 – 2011-01-19 12:28:52

+0

downvote,誓言。 – 2011-01-19 12:54:56

3

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

0

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