简体   繁体   中英

Why auto is deduced to int instead of uint16_t

I have the following code:

uint16_t getLastMarker(const std::string &number);
...
const auto msgMarker = getLastMarker(msg.number) + static_cast<uint16_t>(1);
static_assert(std::is_same<decltype(msgMarker), const int>::value, "Should fail");
static_assert(std::is_same<decltype(msgMarker), const uint16_t>::value, "Should not fail");

and I expect that the first assertion will fail and second one will not. However gcc 4.9.2 and clang 3.6 do the opposite. If I use uint16_t instead of auto in my code proper assertion fails and another one succeeds.

PS Initially I had just 1 instead of static_cast<uint16_t>(1) and thought that the issue is caused by the fact that numeric literal 1 has type int but wrong assertion fails even after explicit cast here.

Addition will perform the usual arithmetic conversions on its operands which in this case will result in the operands being promoted to int due the the integer promotions and the result will also be int .

You can use uint16_t instead of auto to force a conversion back or in the general case you can use static_cast .

For a rationale as to why type smaller than int are promoted to larger types see Why must a short be converted to an int before arithmetic operations in C and C++? .

For reference, from the draft C++ standard section 5.7 Additive operators :

[...]The usual arithmetic conversions are performed for operands of arithmetic or enumeration type[...]

and from section 5 Expressions :

[...]Otherwise, the integral promotions (4.5) shall be performed on both operands. 59 Then the following rules shall be applied to the promoted operands[...]

and from section 4.5 Integral promotions ( emphasis mine ):

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.

Assuming int is larger than 16-bit.

Arithmetic operations don't work on any type smaller than int . So, if uint16_t is smaller than int , it will be promoted to int (or possibly a larger type, if necessary to match the other operand) before performing the addition.

The result of the addition will be the promoted type. If you want another type, you'll have to convert afterwards.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM