I am using IAR (a C compiler) to program for TI chips (16 bits MCU).
I have the following strcture,
//I use union mainly because sometimes I use the 2 bytes word value
// and sometimes I only use one byte (either a or b)
typedef union {
uint16_t address;
struct
{
uint8_t parta;
uint8_t partb;
} details;
} address_t;
Then I have the following mac address definition,
typedef struct
{
uint8_t frame_type;
uint8_t sequence_number;
address_t source_address;
} mac_header_t;
so far so good.
When I receive a packet over radio, it's stored in a buffer array.
uint8_t buffer[MAX_PACKET_LEN];
//the first byte is packet length, mac address follows
mac_header_t *header = (mac_header_t *)(buffer + 1);
The the weird things happens,
//The packet is say
// 0x07 (length)
// 0x07 (frame_type)
// 0x04 (sequence_number)
// 0x00 (source address parta)
// 0x00 (source address partb)
//The source address is indeed 0x00 0x00 (2 bytes)
assert(header->source_address.details.parta == 0); //correct! there's no problem
assert(header->source_address.details.partb == 0); //correct! there's no problem
//assignment from header->source_address to another object
address_t source_address = header->source_address;
assert(source_address.details.parta == 0); //no! it's 0x04!
assert(source_address.details.partb == 0); //this is right
So the weird thing is, after assignment from header->source_address, to another object, the alignment changed from 0x00 0x00 to 0x04 0x00 (note the buffer, this actually moves the pointer 1 byte forward)!
After I used #pragma pack(1), things are solved.
However, I am not sure why this actually caused problem. Assignment of 2 object at different alignment boundary will result in two completely different values? (right hand side is 0x00 0x00, and left hand side is 0x04 0x00)
Is this code undefined in C? Or it's a bug of IAR?
Thanks.
mac_header_tobject manually from the received memory.header = (mac_header_t *)(buffer + 1)any access to the nonuint8_tstrucuture members will violate alignment requirements because of the+ 1.