【发布时间】:2011-07-21 16:38:01
【问题描述】:
正如an answer to this question 中所指出的,编译器(在本例中是 gcc-4.1.2,是的,它很旧,不,我无法更改它)可以在它认为合适的地方用 memcpy 替换结构分配。
我在 valgrind 下运行一些代码并收到有关 memcpy 源/目标重叠的警告。当我查看代码时,我看到了这个(释义):
struct outer
{
struct inner i;
// lots of other stuff
};
struct inner
{
int x;
// lots of other stuff
};
void frob(struct inner* i, struct outer* o)
{
o->i = *i;
}
int main()
{
struct outer o;
// assign a bunch of fields in o->i...
frob(&o.i, o);
return 0;
}
如果 gcc 决定用 memcpy 替换该分配,那么这是一个无效的调用,因为源和目标重叠。
显然,如果我将frob 中的赋值语句改为调用memmove,那么问题就消失了。
但这是一个编译器错误,还是该赋值语句在某种程度上无效?
【问题讨论】:
-
我很确定你的意思是写 frob(..., &o),而不是 (..., 0)。
-
这是一个编译器错误。整个 gcc 4.x 系列充满了这样的废话,包括打破 gcc 1.0 之前的
LIST_ENTRY/LIST_HEAD类型双关语。加入 gcc-4 抵抗! -
@Andy - 我的胖手指。谢谢。
-
@Heath:整个 4.x系列?你是认真地建议我们回到 3.x 吗?或者您是否发明了一台时间机器并且您可以使用令人敬畏的未来派 5.x 系列?
-
接受 Jens 的回答,因为我认为它最清楚地定义了问题。 R.. 认为这是一个 gcc 错误(至少是一个潜伏的错误)可能是正确的,但在我的特定组合中它不是问题。至少我把它改成了 memmove 让 valgrind 闭嘴。感谢您的回答。
标签: c optimization gcc memcpy memmove