C union 中变量的对齐在所有系统上都相同吗?
Will the alignment of variables in a C union be the same on all systems?
考虑以下联合:
typedef union {
struct { // Anonymous struct
int red;
int green;
int blue;
};
int colorChannels[3];
} Color;
无论此代码在哪个系统上编译或执行,匿名结构中的字段是否始终与 colorChannels 中的索引对齐?
也就是说规范要求myColor.colorChannels[0]
的内存地址和myColor.red
的地址一样吗?
此外,如果代码编译为 C++ 而不是 C,答案会有所不同吗?
请注意,我问的是联合中每个元素都具有相同 type/size 的特定情况(即本例中的 int
)
Regardless of the system this code is compiled or executed on, will the fields in the anonymous struct always line up with the indexes in colorChannels?
不一定。该实现可以在 struct
的各个变量之间添加字节 "padding"。 "Padding" 只是以 implementation-defined 的方式在 struct
的变量之间或末尾的内存定义中插入额外的内存字节。如果发生这种情况,那么您的整数数组将不会与 struct
的内存布局对齐(除非填充仅在 struct
的末尾,也许)。 struct
中变量在内存中的顺序应该在不同的实现中保持一致(在那个变量 a
之后是 b
之后是 c
在内存中),但是,同样,之间的字节填充仍然存在(例如,a
在内存中后跟 b
,但 a
和 b
之间存在填充,因此它们不正确在记忆中一个接一个)。
对于 gcc 等编译器,there are ways to modify how it handles padding。这有助于确保 struct
与您的整数数组在内存中对齐,但这可能会导致下游出现其他内存问题。
In other words, does the specification require the memory address of myColor.colorChannels[0] to be the same as the address of myColor.red?
如果 struct
的 red
、green
和 blue
之间没有填充,则 colorChannels
的索引将与内存中的每个变量。
C 标准对此不作任何保证,但它可能在任何实际存在的系统上都是正确的。
我建议在代码中添加一个 compile-time 检查,这样万一有一些系统添加了填充,你会得到一个你可以在当时处理的编译错误:
_Static_assert( sizeof(Color) == 3 * sizeof(int), "We're on a weird system boys." );
注意。 _Static_assert
是在 C11 中添加的,在此之前你可以使用一些 hack as described here
考虑以下联合:
typedef union {
struct { // Anonymous struct
int red;
int green;
int blue;
};
int colorChannels[3];
} Color;
无论此代码在哪个系统上编译或执行,匿名结构中的字段是否始终与 colorChannels 中的索引对齐?
也就是说规范要求myColor.colorChannels[0]
的内存地址和myColor.red
的地址一样吗?
此外,如果代码编译为 C++ 而不是 C,答案会有所不同吗?
请注意,我问的是联合中每个元素都具有相同 type/size 的特定情况(即本例中的 int
)
Regardless of the system this code is compiled or executed on, will the fields in the anonymous struct always line up with the indexes in colorChannels?
不一定。该实现可以在 struct
的各个变量之间添加字节 "padding"。 "Padding" 只是以 implementation-defined 的方式在 struct
的变量之间或末尾的内存定义中插入额外的内存字节。如果发生这种情况,那么您的整数数组将不会与 struct
的内存布局对齐(除非填充仅在 struct
的末尾,也许)。 struct
中变量在内存中的顺序应该在不同的实现中保持一致(在那个变量 a
之后是 b
之后是 c
在内存中),但是,同样,之间的字节填充仍然存在(例如,a
在内存中后跟 b
,但 a
和 b
之间存在填充,因此它们不正确在记忆中一个接一个)。
对于 gcc 等编译器,there are ways to modify how it handles padding。这有助于确保 struct
与您的整数数组在内存中对齐,但这可能会导致下游出现其他内存问题。
In other words, does the specification require the memory address of myColor.colorChannels[0] to be the same as the address of myColor.red?
如果 struct
的 red
、green
和 blue
之间没有填充,则 colorChannels
的索引将与内存中的每个变量。
C 标准对此不作任何保证,但它可能在任何实际存在的系统上都是正确的。
我建议在代码中添加一个 compile-time 检查,这样万一有一些系统添加了填充,你会得到一个你可以在当时处理的编译错误:
_Static_assert( sizeof(Color) == 3 * sizeof(int), "We're on a weird system boys." );
注意。 _Static_assert
是在 C11 中添加的,在此之前你可以使用一些 hack as described here