Reputation: 1
I have a question about implicit type conversions in C++. I'm programming for 32bit ARM microcontroller. If simplified I have the following code:
int32_t globalTimeValue = 0;
uint16_t previuostTimerValue = 0;
void PeriodicTimeUpdateFunction() {
uint16_t curValue = someTimer.currentValue;
// it's only 16 bit because it's a value of some microcontroller timer
globalTimeValue += curValue - previuostTimerValue; // this is the row, that I'm interested in
}
I have always thought that, curValue - previuostTimerValue
will be made as uint16_t
substraction, providing uint16_t
result including overflow (which is exactly what i need, if timer had overrun), and later it will be implicitly converted to int32_t
by means of zero extention and addition will be carried out as 32 bit signed operation.
But instead of zero extending the result of the substraction, the compiler only extends curValue
and previuostTimerValue
, making sure that they are proper 16 bit values. But later the substraction is carried out as native 32bit operation and substraction result is added as 32bit value to globalTimeValue
. Thus essentially it's the same as if i would write:
globalTimeValue += (int32_t)curValue - (int32_t)previuostTimerValue;
Please help me understand, why is my previous understanding incorrect? Why the compiler does not do (curValue - previuostTimerValue) as uint16_t operation with later zero extension to int32_t?
PS: as always, I'm very sorry if this question is already answered - after some search I could not find an answer.
Upvotes: 0
Views: 186
Reputation: 238361
why is my previous understanding incorrect?
Because that's not how the language is specified.
No arithmetic operations are performed on integers that are smaller than int
. On your system, int
is presumably 32 bit type. All integers of smaller types are promoted to int
(if it can represent all values of the smaller type, unsigned int
otherwise).
If you want to have 16 bit roll-over, you can convert the resulting int
back:
globalTimeValue += static_cast<std::uint16_t>(
curValue - previuostTimerValue);
Upvotes: 1