如果结构定义了uint16_t字和uint8_t字节,则数组的大小加倍

我有一个数组,每个数组的元素可以是uint16_t或一对uint8_t。

它的元素被定义为uint16_t和2 uint8_t的子数组的并集。

不幸的是,编译器(MicroChip XC16)分配的内存量应该是arrays的两倍。

typedef union { uint16_t u16; // As uint16_t uint8_t u8[2]; // As uint8_t } my_array_t; my_array_t my_array[1]; // 1 word array, for testing my_array[0].u8[0] = 1; my_array[0].u8[1] = 2; uint8_t byte_0 = my_array[0].u8[0]; // Gets 0x01 uint8_t byte_1 = my_array[0].u8[1]; // Gets 0x02 uint16_t byte_0 = my_array[0].u16; // Gets 0x0201 

编译器应该分配4个字节而不是2个字节。

解决方法:如果我将结构更改为:

 typedef union { uint16_t u16; // As uint16_t uint8_t u8[1]; // As uint8_t } my_array_t; 

编译器应该分配2个字节,但这是不正确的:

 my_array[0].u8[1] = 2; 

虽然它仍然有效:

 uint8_t byte_1 = my_array[0].u8[1]; // Gets 0x02 

(除了调试器没有显示其值的不便之处)。

问题:我应该使用解决方法,还是应该使用更好的解决方案?

请参考之前对此的讨论 ,其中提出了上述解决方案。


编辑。

根据EOF的建议(下图),我检查了sizeof。

解决方法之前:

 sizeof(my_array_t) // Is 4 sizeof(my_array[0]) // Is 4 sizeof(my_array[0].u8) // Is 2 

解决方法之后:

 sizeof(my_array_t) // Is 2 sizeof(my_array[0]) // Is 2 sizeof(my_array[0].u8) // Is 2 

这表明它是一个编译器错误。

而不是2个字节的数组,使用2字节的结构:

 // Two bytes in a 16-bit word typedef struct{ uint8_t lsb; // As uint8_t, LSB uint8_t msb; // As uint8_t. MSB } two_bytes_t; typedef union { uint16_t u16; // As uint16_t two_bytes_t u8x2; // As 2 each of uint8_t } my_array_t; my_array_t my_array[1]; // 1 word array, for testing my_array[0].u8x2.msb = 1; my_array[0].u8x2.lsb = 2; 

XC16编译器为每个元素正确分配2个字节,调试器正确显示各个字节。

看起来这个问题在编译器中得到了修复。 我在XC16 1.26中检查了它并从我的代码中获得了这些结果(优化0):

 #include "mcc_generated_files/mcc.h" #include "stddef.h" typedef union { uint16_t u16; uint8_t u8[2]; } example_1_t; typedef union { uint16_t u16; struct { uint8_t lsb; uint8_t msb; }; } example_2_t; int main(void) { SYSTEM_Initialize(); size_t typeSize1 = sizeof (example_1_t); // debugger shows 2 size_t typeSize2 = sizeof (example_2_t); // debugger shows 2 example_1_t ex1; // Can see all values in debugger ex1.u16 = 0x4321; // u8[0] = 0x21, u8[1] = 0x43 example_2_t ex2; // Can see all values in debugger ex2.u16 = 0x4321; // lsb = 0x21, msb = 0x43 size_t objSize1 = sizeof (ex1); // debugger shows 2 size_t objSize2 = sizeof (ex2); // debugger shows 2 while (1) { } return -1; }