¿Cómo escribo un literal corto en C ++?


120

Pregunta muy básica: ¿cómo escribo un shortliteral en C ++?

Yo se lo siguiente:

  • 2 es un int
  • 2U es un unsigned int
  • 2L es un long
  • 2LL es un long long
  • 2.0f es un float
  • 2.0 es un double
  • '\2'es un char.

Pero, ¿cómo escribiría un shortliteral? Lo intenté, 2Spero eso da una advertencia del compilador.


10
Supongo que el literal corto no se admite únicamente debido al hecho de que cualquier cosa menor que int será "promocionada" a int durante la evaluación. int tiene el tamaño más natural. Esto se denomina promoción de enteros en C ++.
user534498

Respuestas:


82
((short)2)

Sí, no es estrictamente un literal corto, más bien un int casted, pero el comportamiento es el mismo y creo que no hay una forma directa de hacerlo.

Eso es lo que he estado haciendo porque no pude encontrar nada al respecto. Supongo que el compilador sería lo suficientemente inteligente como para compilar esto como si fuera un literal corto (es decir, no asignaría un int y luego lo lanzaría cada vez).

A continuación se muestra cuánto debería preocuparse por esto:

a = 2L;
b = 2.0;
c = (short)2;
d = '\2';

Compilar -> desmontar ->

movl    $2, _a
movl    $2, _b
movl    $2, _c
movl    $2, _d

Eso es lo que he estado haciendo porque no pude encontrar nada al respecto. Supongo que el compilador sería lo suficientemente inteligente como para compilar esto como si fuera un literal corto (es decir, no asignaría un int y luego lo lanzaría cada vez).
Kip

El "elenco" realmente no está haciendo nada. No hay una instrucción de ensamblador "cast" cuando hablamos de C o C ++ (.NET MSIL es una historia diferente). Ahí en el metal, todo son solo dígitos binarios
Isak Savo

9
¿Cuáles son los tipos de a, b, cyd anteriores?
Ates Goral

2
@Ates Goral: Todas las entradas. Cambiar a short o char probablemente cambiaría la instrucción a movw o movb en todos los ámbitos.

2
Eso no es un literal corto. Cuando usa esa conversión y compila con GCC y la opción -Wconversion, aún obtiene un diagnóstico del compilador para la declaración short foo = 1; foo += (short)2;. Pero esto no se puede eludir debido a la promoción de números enteros.
harper

51

C ++ 11 le ofrece bastante cerca de lo que desea. (Busque "literales definidos por el usuario" para obtener más información).

#include <cstdint>

inline std::uint16_t operator "" _u(unsigned long long value)
{
    return static_cast<std::uint16_t>(value);
}

void func(std::uint32_t value); // 1
void func(std::uint16_t value); // 2

func(0x1234U); // calls 1
func(0x1234_u); // calls 2

// also
inline std::int16_t operator "" _s(unsigned long long value)
{
    return static_cast<std::int16_t>(value);
}

6
shortfísicamente no puede ser std::uintnada, ya que es un tipo firmado. Y no se requiere que sea de 16 bits o del mismo tipo que un std::int16_t... que en sí mismo ni siquiera se requiere que exista en una implementación dada si la plataforma no puede suministrar el tipo de ancho exacto. La idea central de esta respuesta es buena, pero está devaluada por la tangente inexplicable en tipos no relacionados sobre los que el OP no preguntó.
underscore_d

Tenga en cuenta que los literales definidos por el usuario no son compatibles con Visual Studio hasta VS2015: msdn.microsoft.com/en-us/library/hh567368(v=vs.140).aspx
parsley72

No sé si debería amarlo u odiarlo, pero esta es la última pieza de mi sistema de tipos enteros Strong en C ++ en la que estoy trabajando, es increíble.
Sahsahae

Haciendo eco de @underscore_d, votaría a favor, pero después de una edición shortsegún lo solicitó OP.
v.oddou

28

Incluso los escritores del estándar C99 quedaron atrapados por esto. Este es un fragmento de la stdint.himplementación de dominio público de Danny Smith :

/* 7.18.4.1  Macros for minimum-width integer constants

    Accoding to Douglas Gwyn <gwyn@arl.mil>:
    "This spec was changed in ISO/IEC 9899:1999 TC1; in ISO/IEC
    9899:1999 as initially published, the expansion was required
    to be an integer constant of precisely matching type, which
    is impossible to accomplish for the shorter types on most
    platforms, because C99 provides no standard way to designate
    an integer constant with width less than that of type int.
    TC1 changed this to require just an integer constant
    *expression* with *promoted* type."
*/

18

Si usa Microsoft Visual C ++, hay sufijos literales disponibles para cada tipo de entero:

auto var1 = 10i8;  // char
auto var2 = 10ui8; // unsigned char

auto var3 = 10i16;  // short
auto var4 = 10ui16; // unsigned short

auto var5 = 10i32;  // int
auto var6 = 10ui32; // unsigned int

auto var7 = 10i64;  // long long
auto var8 = 10ui64; // unsigned long long

Tenga en cuenta que se trata de una extensión no estándar y no es portátil . De hecho, ni siquiera pude encontrar información sobre estos sufijos en MSDN.


1
Cuando traza uno de los sufijos, verá que, por ejemplo, ""ui8se define como '\000', que es esencialmente '\0'.
Nikita

10

También puede utilizar la sintaxis de pseudoconstructor.

short(2)

Lo encuentro más legible que el casting.


4
se llama "expresión de conversión funcional". También me gusta mucho, especialmente cuando programo con la API de Windows.
Klaus Triendl

6

Hasta donde yo sé, no es así, no existe tal sufijo. Sin embargo, la mayoría de los compiladores advertirán si un literal entero es demasiado grande para caber en cualquier variable en la que esté tratando de almacenarlo.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.