Как мне написать короткий литерал в C ++? - PullRequest
107 голосов
/ 16 октября 2008

Очень простой вопрос: как мне написать short литерал в C ++?

Я знаю следующее:

  • 2 является int
  • 2U является unsigned int
  • 2L является long
  • 2LL является long long
  • 2.0f является float
  • 2.0 является double
  • '\2' - это char.

Но как бы я написал short литерал? Я попытался 2S, но это дает предупреждение компилятору.

Ответы [ 6 ]

75 голосов
/ 16 октября 2008
((short)2)

Да, это не совсем короткий литерал, скорее каст-инт, но поведение то же самое, и я думаю, что нет прямого способа сделать это.

Я так и делал, потому что ничего не мог найти по этому поводу. Я бы предположил, что компилятор будет достаточно умен, чтобы скомпилировать его, как если бы он был коротким литералом (то есть он фактически не выделил бы int, а затем приводил бы его каждый раз).

Следующее иллюстрирует, насколько вам следует беспокоиться об этом:

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

Компилировать -> дизассемблировать ->

movl    $2, _a
movl    $2, _b
movl    $2, _c
movl    $2, _d
48 голосов
/ 28 августа 2012

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);
}
27 голосов
/ 16 октября 2008

Даже авторы стандарта 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."
*/
13 голосов
/ 03 июня 2015

Если вы используете 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.

9 голосов
/ 20 апреля 2015

Вы также можете использовать синтаксис псевдо-конструктора.

short(2)

Я нахожу это более читабельным, чем кастинг.

5 голосов
/ 16 октября 2008

Насколько я знаю, нет, такого суффикса нет. Большинство компиляторов предупреждают, если целочисленный литерал слишком велик, чтобы поместиться в любую переменную, в которой вы пытаетесь его сохранить.

...