正如指出的这个问题的答案,编译器(在本例中是 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
相反,问题就会消失。
但这是编译器错误,还是该赋值语句在某种程度上无效?
我认为你混淆了级别。gcc
只要能够保证正确的行为,通过调用其喜欢的任何库函数来替换赋值操作是完全正确的。
这不是“召唤”memcpy
或标准意义上的任何内容。它只是使用其库中的一个函数,该函数可能具有保证正确性的附加信息。的属性memcpy
正如标准中所描述的,这些属性被视为程序员的接口,而不是编译器/环境实现者的接口。
无论是否memcpy
在该实现中,是否实现了一种使其对赋值操作有效的行为是另一个问题。检查这一点甚至检查代码应该不那么困难。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)