I have a few questions regarding the C standard and how it is implemented in gcc.
My task is to check if a checksum is valid for an array of data. The array is unsigned byte values. The checksum is a 16-bit value made up of the last two bytes in the array. I loop through the array and calculate my own version of the checksum, then compare it to the checksum in the array. Here is the code for the comparison:
uint16_t cksum=0; uint8_t data[MAX_VAL]; /* this actually has data in it */ /* snip - calculate cksum */ /* compare calculated cksum to actual */ if (cksum == (data[i]<<8) + data[i+1]) /* good checksum */
What surprised me was that this worked. I originally thought that since data[i] is a uint8_t that shifting it 8 bits would cause it to be 0, so I would lose the high byte of my checksum. However, it appears that data[i] is being promoted to an int (this is what the C standard states) and I am fortunate that an int is 16 bits with the avr target. Is this what is actually happening?
My next question is, how can I insure that the two bytes are being promoted to 16 bits without relying on the compiler to be standards compliant? Would it be this way:
if (cksum == (uint16_t)((data[i]<<8) + data[i+1]))
or this way:
if (cksum == (uint16_t)(data[i]<<8) + (uint16_t)data[i+1])
My feeling is the second way.
Any help or insight would be great.