我知道对于下面的代码,下面的“非法”是未定义的(虽然一些编译器允许它),因为联合成员“a”是活动的,然后我们从联合成员“b”中读取。问题是,“AmILegal”中的代码是否修复了它,还是我在做一些可怕甚至更晦涩的事情?我可以使用 memcpy 来实现相同的效果,还是我在那里调用了另一个未定义的行为?
编辑:也许这个例子不够清楚。我想做的就是激活另一个成员。所以我将浮点数更改为int。虽然看起来很傻,但更接近真实案例。阅读下面的代码。
(是否出于某种原因不允许将一个工会成员复制到另一个工会成员中?)
struct Foo
{
union Bar
{
int a[4];
int b[4];
};
void this_is_Illegal()
{
a[0]=1;
a[1]=2;
a[2]=3;
a[3]=4;
std::cout<<b[0]<<b[1]<<b[2]<<b[3];
}
void but_is_this_Legal?()
{
a[0]=1;
a[1]=2;
a[2]=3;
a[3]=4;
b[0]=a[0];
b[1]=a[1];
b[2]=a[2];
b[3]=a[3];
std::cout<<b[0]<<b[1]<<b[2]<<b[3];
}
void this_looks_scary_but_is_it?()
{
a[0]=1;
a[1]=2;
a[2]=3;
a[3]=4;
//forget portability for this q, assume sizeof(int)==sizeof(float)
//maybe memmove works here as well?
memcpy(b, a, sizeof(int)*4)
std::cout<<b[0]<<b[1]<<b[2]<<b[3];
}
};
如果以上所有内容听起来都不是很有用,请认为 a 实际上是一个与 float[4] 结合的 _m128。位表示始终是准确和正确的。在某个时间点,您将需要实际使用它,并且您需要将它作为浮点数组放在主内存中。“复制指令”实际上是从 _m128 联合成员到 float[4] 成员的 _mm_store_ps。因此,关于 memset 的问题 - 也许这是我需要的更准确的例子......