一份副本如何使用 memcpy 联合简单成员?
How could one copy union simple members with memcpy?
我不太确定关于 memcpy
和 union
普通成员的标准引用。
考虑代码:
struct Test{
union
{
void(*function_p)(void*);
void(*function_p_c)(const void*);
};
Test(const Test &other)
{
using std::memcpy;
memcpy(&function_p, &other.function_p, sizeof(function_p)); //?
memcpy(&function_p_c, &other.function_p_c, sizeof(function_p_c)); //??
}
};
int main(void)
{
Test t1; t1.function_p = NULL; //let it be NULL for c++98 sake
Test t2(t1); // is it safe? does this set new active member of union?
return 0;
}
所以一个问题引出另一个问题:
上面的代码安全吗?还是与 second/first memcpy
的 UB 取决于 union
成员用户已触摸?为两个成员调用 memcpy
是不是太过分了?
如果它不安全,那么我如何在没有一些 flag-of-active-union-member 的情况下实现复制构造函数?
由于两个联合成员在内存中占用相同的 space,第二个 memcpy 将覆盖第一个。
你用两个 memcpy 做的是未定义的行为。
The union is only as big as necessary to hold its largest data member.
The other data members are allocated in the same bytes as part of that
largest member. The details of that allocation are
implementation-defined, and it's undefined behavior to read from the
member of the union that wasn't most recently written. Many compilers
implement, as a non-standard language extension, the ability to read
inactive members of a union.
other
只有 function_p
处于活动状态,第二个 memcopy 触发未定义的行为。
我不太确定关于 memcpy
和 union
普通成员的标准引用。
考虑代码:
struct Test{
union
{
void(*function_p)(void*);
void(*function_p_c)(const void*);
};
Test(const Test &other)
{
using std::memcpy;
memcpy(&function_p, &other.function_p, sizeof(function_p)); //?
memcpy(&function_p_c, &other.function_p_c, sizeof(function_p_c)); //??
}
};
int main(void)
{
Test t1; t1.function_p = NULL; //let it be NULL for c++98 sake
Test t2(t1); // is it safe? does this set new active member of union?
return 0;
}
所以一个问题引出另一个问题:
上面的代码安全吗?还是与 second/first
memcpy
的 UB 取决于union
成员用户已触摸?为两个成员调用memcpy
是不是太过分了?如果它不安全,那么我如何在没有一些 flag-of-active-union-member 的情况下实现复制构造函数?
由于两个联合成员在内存中占用相同的 space,第二个 memcpy 将覆盖第一个。
你用两个 memcpy 做的是未定义的行为。
The union is only as big as necessary to hold its largest data member. The other data members are allocated in the same bytes as part of that largest member. The details of that allocation are implementation-defined, and it's undefined behavior to read from the member of the union that wasn't most recently written. Many compilers implement, as a non-standard language extension, the ability to read inactive members of a union.
other
只有 function_p
处于活动状态,第二个 memcopy 触发未定义的行为。