【发布时间】:2012-07-15 09:04:33
【问题描述】:
我知道对于下面的代码,下面的“Illegal”是未定义的(虽然一些编译器允许它),因为联合成员“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 的问题 - 也许这是我需要的更准确的例子......
【问题讨论】:
-
能贴出相关源码吗?
-
"所以我将 float 更改为 int。" 我不明白您要做什么;是否要将 (
int,float) 的位模式解释为 (float,int)? (这就是所谓的“类型双关语”。) -
伙计们,请阅读代码下方的最后一段。我正在准确地解释真实的用例,但是因为真实的代码使用的是 VC++ 编译器内在函数等。在这里使用会很不可读。用例将 __m128 的内存位置作为浮点数 [4] 返回(这几乎是它的定义),同时确保定义了行为。
-
但是在你的例子中甚至没有一个
float声明! -
有,但它只是让人们试图推断我想对浮点数中的数据做什么而混淆了事情,我删除了它,因为数据类型对 q 无关紧要:我只是想知道我问什么:是否可以通过从另一个枚举成员写入来激活非活动枚举成员。 __m128 是困扰我的具体案例,但我想要一个通用的答案。
标签: c++ unions strict-aliasing