假设我有一个结构,不管它是联合的还是其他的:
typedef struct {
union {
struct { float x, y, z; } xyz;
struct { float r, g, b; } rgb;
float xyz[3];
} notAnonymous;
} Vector3;我听说有些编译器会自动填充结构,通过创建单词对齐的边界来增强性能。
假设这样的协同作用意味着结构的大小不能保证是它的组件字段大小的总和,因此在下面的数组xyzs中存在数据损坏和/或溢出的变化:
inline Vector3 v3Make(float x, float y, float z) { Vector3 v = {x,y,z}; return v; }
float xyzs[6];
*(Vector3*)&xyzs[3] = v3Make(4.0f,5.0f,6.0f);
*(Vector3*)&xyzs[0] = v3Make(1.0f,2.0f,3.0f);对,是这样?
发布于 2012-01-12 06:18:06
这是真的,编译器可以用它想要的任何类型的填充来放置我们的结构。您可以使用#pragma pack或__attribute__((packed))来避免在大多数编译器上进行填充。在实践中,您有三个32位字段,所以这可能不是问题。您可以通过对您的结构类型或该类型的变量使用sizeof进行检查,并查看结果。
问题是,您试图在最后两行中为float变量分配一个Vector3。这是不允许的。你可以黑进你想要做的事情:
*(Vector3 *)&xyzs[3] = v3Make(4.0f, 5.0f, 6.0f);但这看起来相当丑陋,更不用说令人困惑了。将xyzs更改为Vector3数组比仅float数组要好得多。
发布于 2012-01-12 06:20:36
参见C缺陷报告#074中问题的答案
http://www.open-std.org/jtc1/sc22/wg14/docs/rr/dr_074.html
发布于 2012-01-12 06:34:58
它本身并不是不安全的,编译器/链接器负责所有的偏移量。
,除非...you将该结构传递给用另一种语言编写的另一程序或另一系统上的另一程序,或者传递给同一系统上用同一语言编写但具有不同编译器设置的另一程序。则可能无法正确计算偏移量。
https://stackoverflow.com/questions/8827464
复制相似问题