user2949923
user2949923

Reputation: 1

Implicit conversions in C++ addition

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

Answers (1)

eerorika
eerorika

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

Related Questions