考虑以下结构:
struct Vector4D
{
union
{
double components[4];
struct { double x, y, z, t; } Endpoint;
};
};
在我看来,我在WinApi的IPAddress结构中看到了类似的东西。我的想法是让我可以通过索引和名称来使用数组组件,例如:
Vector4D v;
v.components[2] = 3.0;
ASSERT(v.Endpoint.z == 3.0) //let's ignore precision issues for now
在C ++标准中,保证在POD结构的开头不会有“空”空间,也就是说,元素x将位于Endpoint结构的beginnig中。目前很好。但我似乎没有找到任何保证在x
和y
或y
和z
之间没有空格或填充的情况,我没有检查出C99标准。
问题是如果Endpoint结构元素之间有空格,那么这个想法将无效。
的的问题: 的
我是对的,确实无法保证这在C或C ++中都有效。
这实际上适用于任何已知的实现吗?换句话说,你知道任何不起作用的实现吗?
是否有任何标准(我的意思是不是编译器特定的)表达相同想法的方式?也许C ++ 0x对齐功能可能会有所帮助吗?
顺便说一句,这不是我在生产代码中所做的事情,不用担心,只是好奇。提前谢谢。
答案 0 :(得分:5)
.z()
而不只是.z
)大多数编译器应该支持使用pragma或属性压缩结构。例如#pragma pack
。
答案 1 :(得分:4)
只要在类中的引用之前声明数组以确保它们指向有效数据,就可以通过引用数组的每个元素来规避任何内存对齐问题。话虽如此,我怀疑对齐是双打的问题,但可能是其他类型(也许在64位拱上漂浮?)
#include <iostream>
using namespace std;
struct Vector4D
{
Vector4D() : components(), x(components[0]), y(components[1]), z(components[2]), t(components[3]) { }
double components[4];
double& x;
double& y;
double& z;
double& t;
};
int main()
{
Vector4D v;
v.components[0] = 3.0;
v.components[1] = 1.0;
v.components[2] = 4.0;
v.components[3] = 15.0;
cout << v.x << endl;
cout << v.y << endl;
cout << v.z << endl;
cout << v.t << endl;
}
希望这有帮助。
答案 2 :(得分:2)
当涉及到标准时,它有两个问题:
说到这一点,实际上这将适用于普通的编译器。事实上,这种代码广泛传播,通常用于将一种类型的值重新解释为另一种类型的值。
答案 3 :(得分:0)
填充字节不会导致问题,因为所有变量都是double
类型。编译器会将Vector4D
视为double
数组。这意味着,v.Endpoint.z
与v[2]
基本相同。