C ++에서 짧은 리터럴을 어떻게 작성합니까?


120

아주 기본적인 질문 : shortC ++ 로 리터럴을 어떻게 작성 합니까?

다음을 알고 있습니다.

  • 2 이다 int
  • 2U 이다 unsigned int
  • 2L 이다 long
  • 2LL 이다 long long
  • 2.0f 이다 float
  • 2.0 이다 double
  • '\2'입니다 char.

하지만 어떻게 short리터럴을 쓸까요? 시도 2S했지만 컴파일러 경고가 표시됩니다.


10
짧은 리터럴은 평가 중에 int보다 작은 것은 int로 "승격"된다는 사실 때문에 단독으로 지원되지 않는다고 생각합니다. int는 가장 자연스러운 크기입니다. 이를 C ++에서 정수 승격이라고합니다.
user534498

답변:


82
((short)2)

예, 엄밀히 말하면 짧은 리터럴이 아니고 캐스트 인트에 가깝지만 동작은 동일하며 직접적인 방법이 없다고 생각합니다.

내가 그것에 대해 아무것도 찾을 수 없었기 때문에 그것이 내가했던 일입니다. 나는 컴파일러가 이것을 짧은 리터럴 인 것처럼 컴파일하기에 충분히 똑똑 할 것이라고 생각한다.

다음은 이에 대해 얼마나 걱정해야 하는지를 보여줍니다.

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

컴파일-> 분해->

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

내가 그것에 대해 아무것도 찾을 수 없었기 때문에 그것이 내가했던 일입니다. 나는 컴파일러가 이것을 짧은 리터럴 인 것처럼 컴파일하기에 충분히 똑똑 할 것이라고 생각한다.
Kip

"캐스트"는 실제로 아무것도하지 않습니다. C 또는 C ++에 대해 이야기 할 때 "캐스트"어셈블러 명령이 없습니다 (.NET MSIL은 다른 이야기입니다). 금속에는 모두 이진수입니다
Isak Savo

9
위의 a, b, c 및 d의 유형은 무엇입니까?
Ates Goral

2
@Ates Goral : 모든 정수. short 또는 char로 변경하면 아마도 전체적으로 명령이 movw 또는 movb로 변경됩니다.

2
그것은 짧은 문자가 아닙니다. GCC 및 -Wconversion 옵션과 함께 해당 캐스트 및 컴파일을 사용하면 명령문에 대한 컴파일러 진단이 계속 제공 short foo = 1; foo += (short)2;됩니다. 그러나 이것은 정수 프로모션으로 인해 피할 수 없습니다.
harper 2014 년

51

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);
}

6
shortstd::uint서명 된 유형이므로 물리적으로 아무것도 될 수 없습니다 . 플랫폼이 정확한 너비 유형을 제공 할 수없는 경우 주어진 구현 std::int16_t존재 하지 않아도되는 16 비트 또는 동일한 유형일 필요는 없습니다 . 이 답변의 핵심 아이디어는 좋지만 OP가 묻지 않은 관련없는 유형에 대한 설명 할 수없는 접선에 의해 평가 절하됩니다.
underscore_d

사용자 정의 리터럴은 VS2015까지 Visual Studio에서 지원되지 않습니다. msdn.microsoft.com/en-us/library/hh567368(v=vs.140).aspx
parsley72

내가 그것을 좋아해야하는지 싫어해야하는지 모르겠지만 이것은 내가 작업중인 C ++의 실제로 Strong 정수 유형 시스템 의 마지막 부분 입니다. 놀랍습니다.
Sahsahae

@underscore_d를 에코하면 upvote하지만 shortOP에 의해 편집 한 후에 .
v.oddou

28

C99 표준의 작성자조차도 이것에 사로 잡혔습니다. 다음은 Danny Smith의 공개 도메인 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."
*/

18

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에서 이러한 접미사에 대한 정보도 찾을 수 없었습니다.


1
당신이 접미사 중 하나를 추적 할 때, 당신은 그 예를 볼 수 있습니다 ""ui8로 정의 '\000'기본적으로 인 '\0'.
Nikita

10

의사 생성자 구문을 사용할 수도 있습니다.

short(2)

캐스팅보다 더 읽기 쉽습니다.


4
"기능적 캐스트 표현"이라고합니다. 특히 Windows API로 프로그래밍 할 때 매우 좋아합니다.
klaus triendl

6

내가 아는 한, 그런 접미사는 없습니다. 하지만 대부분의 컴파일러는 정수 리터럴이 너무 커서 저장하려는 변수에 맞지 않으면 경고합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.