variable uint8_t uint32_t int64_t int32_t int16_t cppreference and c++ c++11 auto integer-promotion

c++ - uint32_t - uint8_t cppreference



Por qué auto se deduce a int en lugar de uint16_t (2)

La adición realizará las conversiones aritméticas habituales en sus operandos, lo que en este caso dará como resultado que los operandos se promuevan a int debido a las promociones de enteros y el resultado también será int .

Puede usar uint16_t en lugar de auto para forzar una conversión o, en el caso general, puede usar static_cast .

Para una explicación de por qué el tipo más pequeño que int se promueve a tipos más grandes, consulte ¿Por qué un corto debe convertirse en un int antes de las operaciones aritméticas en C y C ++? .

Para referencia, del borrador de la norma C ++ sección 5.7 Operadores aditivos :

[...] Las conversiones aritméticas habituales se realizan para operandos de tipo aritmético o de enumeración [...]

y de la sección 5 Expresiones :

[...] De lo contrario, las promociones integrales (4.5) se realizarán en ambos operandos. 59 Entonces se aplicarán las siguientes reglas a los operandos promovidos [...]

y de la sección 4.5 promociones integrales ( énfasis mío ):

Un prvalue de un tipo entero distinto de bool, char16_t, char32_t o wchar_t cuyo rango de conversión de entero (4.13) es menor que el rango de int puede convertirse en un prvalue de tipo int si int puede representar todos los valores del tipo fuente ; de lo contrario, el valor de origen se puede convertir en un valor de tipo unsigned int.

Suponiendo que int es mayor que 16 bits.

Tengo el siguiente código:

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");

y espero que la primera afirmación falle y la segunda no. Sin embargo, gcc 4.9.2 y clang 3.6 hacen lo contrario. Si utilizo uint16_t en lugar de auto en mi código, la aserción correcta falla y otra tiene éxito.

PS Inicialmente solo tenía 1 lugar de static_cast<uint16_t>(1) y pensé que el problema se debe al hecho de que el literal numérico 1 tiene el tipo int pero la afirmación incorrecta falla incluso después de la static_cast<uint16_t>(1) explícita aquí.


Las operaciones aritméticas no funcionan en ningún tipo más pequeño que int . Por lo tanto, si uint16_t es más pequeño que int , se promoverá a int (o posiblemente un tipo más grande, si es necesario para que coincida con el otro operando) antes de realizar la adición.

El resultado de la adición será el tipo promocionado. Si quieres otro tipo, tendrás que convertir después.