【问题标题】:C structure assignment of same address valid?相同地址的C结构分配有效吗?
【发布时间】:2011-06-11 16:29:42
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: c pointers structure variable-assignment memcpy


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      这对我来说看起来完全正确。是的,这将产生一种memcpy

      像这样指向struct 的两个指针只能相同或根本不重叠。所以你可以先检查一下指针是否相等。

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

      【讨论】:

      • 不需要检查。
      【解决方案3】:

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

      【讨论】:

      • 或者知道 memcpy 在这种情况下是有效的:很可能 memcpy 的大多数实现都存在部分重叠但没有完全重叠的问题;和 *x = *y 可能不会导致符合代码的部分重叠。
      【解决方案4】:

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

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

      应满足以下条件之一:

      ...

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

      ...

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

      因此,只要指针相同(即完全重叠),就可以了。尽管 memcpy 的规范说不允许重叠,但编译器有时会为此插入对 memcpy 的调用似乎仍然很奇怪。也许编译器对 memcpy 的特定实现的了解比文档所隐瞒的更多..

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-29
        • 1970-01-01
        • 2016-03-14
        • 2021-04-04
        • 1970-01-01
        相关资源
        最近更新 更多