Как мне написать короткий литерал на C ++?
Вопрос
Очень простой вопрос:как мне написать short
литерал в C ++?
Я знаю следующее:
2
являетсяint
2U
являетсяunsigned int
2L
являетсяlong
2LL
являетсяlong long
2.0f
являетсяfloat
2.0
являетсяdouble
'\2'
являетсяchar
.
Но как бы я написал short
буквально?Я пытался 2S
но это выдает предупреждение компилятора.
Решение
((short)2)
Да, это не совсем короткий литерал, скорее приведенное значение int, но поведение такое же, и я думаю, что прямого способа сделать это нет.
Это то, что я делал, потому что я ничего не мог найти по этому поводу.Я бы предположил, что компилятор был бы достаточно умен, чтобы скомпилировать это так, как если бы это был короткий литерал (т. е.на самом деле это не означало бы выделять int и затем приводить его каждый раз).
Следующее иллюстрирует, насколько сильно вам следует беспокоиться по этому поводу:
a = 2L;
b = 2.0;
c = (short)2;
d = '\2';
Скомпилировать -> разобрать ->
movl $2, _a
movl $2, _b
movl $2, _c
movl $2, _d
Другие советы
C ++ 11 дает вам довольно близкое к тому, что вы хотите. (Найдите "пользовательские литералы", чтобы узнать больше.)
#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);
}
Это застало врасплох даже разработчиков стандарта C99.Это фрагмент из книги Дэнни Смита "Общественное достояние" stdint.h
реализация:
/* 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."
*/
Если вы используете Microsoft Visual C ++, для каждого целочисленного типа доступны литеральные суффиксы:
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
Обратите внимание, что это нестандартные расширения и не являются портативными.На самом деле, я даже не смог найти никакой информации об этих суффиксах в MSDN.
Вы также можете использовать синтаксис псевдоконструктора.
short(2)
Я нахожу это более читабельным, чем кастинг.
Насколько я знаю, у вас нет такого суффикса.Однако большинство компиляторов будут предупреждать, если целочисленный литерал слишком велик, чтобы поместиться в любой переменной, в которой вы пытаетесь его сохранить.