EKW*_*EKW 11 c memory struct unions
考虑以下联合:
typedef union {
struct { // Anonymous struct
int red;
int green;
int blue;
};
int colorChannels[3];
} Color;
Run Code Online (Sandbox Code Playgroud)
无论系统编译或执行此代码的系统如何,匿名结构中的字段是否总是与colorChannels中的索引对齐?
换句话说,规范是否要求内存myColor.colorChannels[0]地址与myColor.red?的地址相同?
另外,如果代码编译为C++而不是C,答案会有所不同吗?
请注意,我问的是联合中每个元素具有相同类型/大小的特定情况(即int在这种情况下)
无论系统编译或执行此代码的系统如何,匿名结构中的字段是否总是与colorChannels中的索引对齐?
不必要.实现可以在单个变量之间添加字节"填充" struct."填充"只是struct在实现定义的方式的变量之间或结尾处插入到存储器定义中的附加字节存储器.如果发生这种情况,那么你的整数数组将不会与内存布局对齐struct(除非填充只是在结束时struct,也许).在该变量的顺序struct在存储器应该是各个实现之间不一致(在该变量a之后,将b随后c在存储器中),但是,再次,之间仍然可以存在的字节的填充(例如,a后面是b在内存中,但有在它们之间填充a并使b它们在存储器中彼此不是正确的).
对于像gcc这样的编译器,有一些方法可以修改它如何处理填充.这可以帮助保证struct与整数数组的内存对齐,但这可能会导致下游的其他内存问题.
换句话说,规范是否要求myColor.colorChannels [0]的内存地址与myColor.red的地址相同?
如果之间没有填充red,green和blue的struct,那么索引colorChannels将匹配了存储器中的每个变量.
C标准对此没有任何保证,但它可能对任何存在的实际系统都是正确的.
我建议在代码中添加一个编译时检查,这样如果有一些系统添加了填充,你会得到一个编译错误,你可以在那时处理:
_Static_assert( sizeof(Color) == 3 * sizeof(int), "We're on a weird system boys." );
Run Code Online (Sandbox Code Playgroud)
NB._Static_assert在C11中添加了,在此之前你可以使用这里描述的一些hack