Come faccio a scrivere un breve letterale in C ++?
Domanda
Domanda molto semplice: come posso scrivere un short
letterale in C ++?
Conosco quanto segue:
-
2
è unint
-
2U
è ununsigned int
-
2L
è unlong
-
2LL
è unlong long
-
2.0f
è unfloat
-
2.0
è undoppio
-
'\ 2'
è uncarattere
.
Ma come dovrei scrivere un short
letterale? Ho provato 2S
ma mi dà un avvertimento sul compilatore.
Soluzione
((short)2)
Sì, non è strettamente un letterale breve, più un cast-int, ma il comportamento è lo stesso e penso che non ci sia un modo diretto per farlo.
Questo è quello che ho fatto perché non sono riuscito a trovare nulla al riguardo. Immagino che il compilatore sarebbe abbastanza intelligente da compilare questo come se fosse un letterale breve (cioè non assegnerebbe effettivamente un int e poi lo lancerebbe ogni volta).
Quanto segue illustra quanto dovresti preoccuparti di questo:
a = 2L;
b = 2.0;
c = (short)2;
d = '\2';
Compila - > disassemblare - >
movl $2, _a
movl $2, _b
movl $2, _c
movl $2, _d
Altri suggerimenti
C ++ 11 ti dà abbastanza vicino a quello che vuoi. (Cerca " letterali definiti dall'utente " per saperne di più.)
#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);
}
Anche gli scrittori dello standard C99 ne sono stati sorpresi. Questo è un frammento dell'implementazione stdint.h
di dominio pubblico di 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."
*/
Se si utilizza Microsoft Visual C ++, sono disponibili suffissi letterali per ogni tipo di numero intero:
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
Nota che si tratta di estensioni non standard e non sono portatili . In effetti, non sono riuscito a trovare alcuna informazione su questi suffissi su MSDN.
Puoi anche usare la sintassi dello pseudo costruttore.
short(2)
Lo trovo più leggibile del casting.
Per quanto ne so, non esiste un suffisso del genere. La maggior parte dei compilatori avviserà se un valore intero letterale è troppo grande per adattarsi a qualsiasi variabile in cui si sta tentando di memorizzarlo.