该问题的答案中指出,编译器(在此case gcc-4.1.2,是的,它已经很旧了,不,我不能更改它)可以在认为合适的地方用memcpy替换结构分配。

我正在valgrind下运行一些代码,并收到有关memcpy源/目标重叠的警告。当我查看代码时,我看到以下内容(解释): 通用标签

如果gcc决定用memcpy替换该赋值,则该调用无效,因为源和目标重叠。

很明显,如果我将frob中的赋值语句更改为改为调用memmove,那么问题就消失了。

但这是编译器错误,还是该赋值语句某种程度上无效?

有帮助吗?

解决方案

我认为您正在混淆各个级别。只要能保证正确的行为,gcc完全可以通过调用任何喜欢的库函数来代替赋值操作。

在标准的意义上,这不是“调用” memcpy或任何东西。它只是在其库中使用一个函数,因此它可能具有其他保证正确性的信息。标准中所描述的memcpy的属性是被视为程序员接口的属性,而不是编译器/环境实现程序的接口。

该实现中的memcpy是否实现了使其对赋值操作有效的行为是另一个问题。检查代码甚至检查代码都不难。

其他提示

据我所知,这是一个编译器错误。由于类型匹配且编译器无法证明先前无法获取i的地址,因此允许&o.i根据别名规则对o.i进行别名。当然,使用重叠(或相同)指针调用memcpy会调用UB。

顺便说一句,在您的示例中,o->i是胡说八道。你的意思是我认为o.i ...

我想这里有一个错字:“&o”而不是“ 0”。 在此假设下,“重叠”实际上是严格的覆盖:memcpy(&o-> i,&o-> i,sizeof(o-> i))。在这种特殊情况下,memcpy的行为正确。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top