Why does the following code produce a C192: '=': value truncated error? They are all uint8_t's. Structure definition shown below. What is there to truncate, all variables are of the exact same type! The result is correct but I am just interested in why.
msg.DataBuffer[7] = msg.DataBuffer[0] ^ msg.DataBuffer[1] ^ msg.DataBuffer[6];
typedef struct { uint16_t CANID; uint8_t DataBuffer[8]; uint8_t DataSize; } CAN_MESSAGE;
The intermediate result of the XOR operation (as other operations too) has the default data type. If that default data type is larger than the variable size on the left, it must be truncated. However, this should not be an 'error' as you write, it should be a 'warning' only.
integer promotion?
You seem to be expressing a doubt. Why?
... it should be a 'warning' only.
Probably the OP misreported the message.
http://www.keil.com/support/docs/2569.htm
It seems that Keil also mis-documented it:
http://www.keil.com/support/man/docs/c166/c166_c192.htm
It is a warning (C192), sorry about that.
I still don't understand why there is an intermediate result (probably of type int) that is not of type unsigned char. Why is the intermediate result of the last xor not of type unsigned char (from what i read it is promoted to int)? But when there is only two things being xord there is no promotion?
This produces a warning:
This doesn't:
msg.DataBuffer[7] = msg.DataBuffer[0] ^ msg.DataBuffer[1];
Neither does this:
msg.DataBuffer[7] = msg.DataBuffer[0] ^ (unsigned char)(msg.DataBuffer[1] ^ msg.DataBuffer[6]);
I still don't understand why there is an intermediate result (probably of type int) that is not of type unsigned char.
Because the language is defined that way.
But when there is only two things being xord there is no promotion?
Not quite. There is always promotion. There is just no warning about it in that case.