2

Update

Can anyone explain the reason for promoting uint8_t to int? What are the use cases for this behavior? And can I prevent the promoting?


I have these very simple code snippets which add two integer types together and print the result. I have compiled those without any optimization with g++ --std=c++11 main.cpp -o test

int main()
{
    uint8_t a = 200, b = 100;
    uint16_t result = (a + b);

    printf("result is %d\n", result);
}

Outputs:

result is 300

I would have expected (a + b) to evaluate to 44 because they are both of an 8-bit type and should overflow. But instead I get the unexpected result of 300.


If I re-run the same test with uint32_t and uint64_t, it is overflowing as expected:

int main()
{
    uint32_t a = UINT_MAX, b = UINT_MAX;
    uint64_t result = (a + b);

    printf("result is %ld\n", result);
}

Outputs:

result is 4294967294

Now I can't tell why uint8_t is treated differently to uint32_t.

bricklore
  • 4,125
  • 1
  • 34
  • 62
  • i susptect he means uint23_t a=... but cut and paste the wrong line when posting here – pm100 Sep 11 '15 at 19:11
  • @pm100 yes, as I already stated you're right and i just forgot to paste UINT_MAX there – bricklore Sep 11 '15 at 19:12
  • Please do not use printf %expected-type –  Sep 11 '15 at 19:13
  • @DieterLücking Can you state a reason why i shouldn't do this? At the time the printf is called, the result has been evaluated either way. So it's perfectly safe to use this – bricklore Sep 11 '15 at 19:16
  • Also see [Why must a short be converted to an int before arithmetic operations in C and C++?](http://stackoverflow.com/q/24371868/1708801) – Shafik Yaghmour Sep 11 '15 at 19:30

2 Answers2

8

integral types smaller than int are promoted to int when operations are performed on them

pm100
  • 48,078
  • 23
  • 82
  • 145
1

C++ Standard: 5.10

— Otherwise, the integral promotions (4.5) shall be performed on both operands. Then the following rules shall be applied to the promoted operands: — If both operands have the same type, no further conversion is needed.

4.5.1 Integral promotions

A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int.

This is most probably the reason:

3.9.1 Fundamental types

Plain ints have the natural size suggested by the architecture of the execution environment; the other signed integer types are provided to meet special needs.

Slava
  • 43,454
  • 1
  • 47
  • 90