You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中结构体自赋值(指针解引用)是否为定义行为?

C语言结构体自赋值的合法性问题

问题描述

若两个指针指向同一个结构体变量,对其中一个解引用后赋值给另一个解引用的指针,该行为是否属于C标准定义的合法行为?

代码示例

struct Struct {
    int member;
};

int main() {
    struct Struct s, *p1, *p2;
    s.member = 1234;
    p1 = p2 = &s;
    *p1 = *p2; // is this allowed?
}

疑问背景

在Stack Overflow相关讨论中,有观点提到结构体赋值大致等效于memcpy,部分编译器甚至会将赋值语句编译为memcpy调用。但memcpy在内存区域重叠时行为未定义,因此疑惑结构体自赋值的行为是否符合标准定义。此外,是否需要添加判断语句if (p1 != p2) *p1 = *p2;或改用memmove?

补充场景

该问题源于在C语言中实现slot map时,删除元素会将数组末尾元素复制到删除位置,当删除的是末尾元素时会出现自赋值情况。

解答

  • 结构体自赋值是C标准明确允许的合法行为,不存在未定义行为。
  • 虽然部分编译器会用memcpy实现结构体赋值,但C标准要求编译器必须保证自赋值场景的安全性:当检测到赋值操作的左右操作数指向同一对象时,编译器不能直接使用存在未定义行为的memcpy,而是会采用安全的实现方式(比如等价于memmove的逻辑,或者逐个成员复制)。
  • 不需要额外添加if (p1 != p2)判断,也不需要改用memmove。直接编写*p1 = *p2即可,无论两个指针是否指向同一对象,标准都保证行为是定义良好的。
  • 针对slot map的场景:删除末尾元素时的自赋值完全安全,无需额外处理,直接执行赋值语句即可。

内容的提问来源于stack exchange,提问作者Michael Jones

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 21:45:05