C ++で短いリテラルを書き込むにはどうすればよいですか?


120

非常に基本的な質問:shortC ++でリテラルをどのように書くのですか?

私は次のことを知っています:

  • 2int
  • 2Uunsigned 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)

ええ、それは厳密には短いリテラルではなく、キャストされた整数ですが、動作は同じであり、直接実行する方法はないと思います。

私はそれについて何も見つけることができなかったので、私がやっていました。コンパイラーはこれを短いリテラルであるかのようにコンパイルするのに十分スマートだと思います(つまり、実際にintを割り当てて毎回キャストするわけではありません)。

以下は、これについてどれだけ心配する必要があるかを示しています。

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

コンパイル->逆アセンブル->

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

私はそれについて何も見つけることができなかったので、私がやっていました。コンパイラーはこれを短いリテラルであるかのようにコンパイルするのに十分スマートだと思います(つまり、実際にintを割り当てて毎回キャストするわけではありません)。
Kip

「キャスト」は実際には何もしていません。CまたはC ++の場合、「キャスト」アセンブラー命令はありません(ただし、.NET MSILは別の話です)。金属上では、すべて2進数です
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;ます。しかし、これは整数の昇格のために回避できません。
14年

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署名されたタイプであるため、物理的には何もできません。また、プラットフォームが正確な幅の型を提供できない場合、16ビットまたはstd::int16_t...と同じ型である必要はありません。これ自体は、特定の実装に存在する必要さえありません。この回答の核となる考え方は良いですが、不可解な正接によって、OPが要求しなかった無関係なタイプに切り下げられます。
underscore_d

ユーザー定義のリテラルはVS2015までVisual Studioではサポートされないことに注意してください
v

好きか嫌いかはわかりませんが、これは私が取り組んでいるC ++の実際のストロング整数型システムの最後のピースです。素晴らしいです。
Sahsahae、

@underscore_dをエコーし​​て、私は賛成票を投じますが、編集後に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
あなたは接尾辞の1をトレースするときは、その例が表示されます""ui8ように定義されて'\000'本質的です、'\0'
Nikita

10

疑似コンストラクター構文を使用することもできます。

short(2)

キャストより読みやすいと思います。


4
「関数型キャスト表現」と呼ばれています。特にWindows APIを使用してプログラミングする場合も、とても気に入っています。
klaus triendl 2017

6

私が知る限り、そうではありません。そのような接尾辞はありません。ただし、ほとんどのコンパイラは、整数リテラルが大きすぎて、格納しようとしている変数に収まらない場合に警告します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.