Comment écrire un littéral court en C ++?
Question
Question très basique: comment écrire un littéral short
en C ++?
Je sais ce qui suit:
-
2
est unint
-
2U
est unentier non signé
-
2L
est unlong
-
2LL
est unlong long
-
2.0f
est unfloat
-
2.0
est undouble
-
'\ 2'
est uncaractère
.
Mais comment pourrais-je écrire un littéral short
? J'ai essayé 2S
mais cela donne un avertissement au compilateur.
La solution
((short)2)
Oui, ce n'est pas strictement un littéral court, mais plutôt un casted-int, mais le comportement est le même et je pense qu'il n'y a pas de moyen direct de le faire.
C'est ce que je fais parce que je n'ai rien trouvé à ce sujet. Je suppose que le compilateur serait assez intelligent pour le compiler comme s’il s’agissait d’un littéral court (c’est-à-dire qu’il n’allouerait pas réellement un int et le lirait à chaque fois).
Les éléments suivants illustrent à quel point vous devriez vous inquiéter à ce sujet:
a = 2L;
b = 2.0;
c = (short)2;
d = '\2';
Compiler - > démonter - >
movl $2, _a
movl $2, _b
movl $2, _c
movl $2, _d
Autres conseils
C ++ 11 vous donne à peu près ce que vous voulez. (Recherchez des "littéraux définis par l'utilisateur" pour en savoir plus.)
#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);
}
Même les rédacteurs de la norme C99 ont été pris au dépourvu. Ceci est un extrait de la mise en oeuvre de stdint.h
du domaine public 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."
*/
Si vous utilisez Microsoft Visual C ++, des suffixes littéraux sont disponibles pour chaque type d'entier:
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
Notez que ce sont des extensions non standard et non portables . En fait, je ne pouvais même pas localiser d’informations sur ces suffixes sur MSDN.
Vous pouvez également utiliser la syntaxe du pseudo constructeur.
short(2)
Je le trouve plus lisible que le casting.
Autant que je sache, vous n’avez pas ce suffixe. La plupart des compilateurs avertiront cependant si un littéral entier est trop grand pour tenir dans la variable dans laquelle vous essayez de le stocker.