直接memcpy数据至union而非其特定成员是否安全?
关于Union与memcpy的安全性问题
嘿,这个问题问到点子上了,刚好涉及C++里union和可平凡复制类型的核心规则,我给你掰扯清楚:
先给结论:两种memcpy写法都安全,但细节和可读性有区别
不管是直接把数据memcpy到union对象本身,还是明确memcpy到它的f成员,之后访问b.f都是合法安全的,但我们得搞明白背后的原因,还有哪种写法更适合你的模板场景。
1. 直接memcpy到Union对象本身的情况
当你执行memcpy(&b, &f, sizeof(f));时,因为foo是可平凡复制类型,而且union blah的第一个成员就是foo f——根据C++标准,union对象的地址和它第一个成员的地址是完全重合的(也就是&b == &b.f)。说白了,你这操作本质上就是把f的字节复制到了b.f的内存区域里。
之后把b.f当活跃成员用完全没问题:可平凡复制类型的特点就是不需要显式构造,直接通过字节复制就能合法创建有效对象。这时候b.f自然就成了union的活跃成员,完全符合标准要求。
2. memcpy到Union特定成员的情况
memcpy(&b.f, &f, sizeof(f));这种写法更直白,效果和第一种完全一样,但胜在可读性拉满——谁看都知道你是要初始化union的f成员,不会有任何歧义。
给你模板函数的建议
如果你要写template<int c> void init_union(blah& b...)这类模板,我强烈推荐第二种写法(直接memcpy到目标成员),原因有两个:
- 维护性更强:哪怕以后有人修改union的成员顺序(比如把
bar挪到第一个),你的代码依然能精准初始化f成员,不会因为内存布局变化出问题; - 意图更清晰:模板代码本身就容易抽象,明确指定操作的成员能让后续读代码的人一眼get到你的逻辑,减少踩坑概率。
最后补个小提醒:只要你操作的是可平凡复制类型,且源数据是该类型的有效对象,不管哪种memcpy方式都不会踩标准的红线——可平凡复制类型的设计初衷就是支持这种字节级的复制操作嘛。
内容的提问来源于stack exchange,提问作者jcarpenter2
相关产品推荐
相关产品推荐

