L
接尾辞は、数値リテラルの型が であることを示すために使用されますlong int
。通常、変数に値を割り当てるだけの場合は必要ありません。C++11 §2.14.2 ¶2 (および特に表 6) に関しては、接尾辞のない 10 進整数リテラルが最初の型になるためです。int
、long int
またはの間で表すことができlong long int
ます。1
したがって、値自体が切り捨てられるリスクはありません。しかし:
- リテラルの型についてある程度の不確実性があります(プラットフォーム/コンパイラに応じて
32768
、int
または aの場合があります)。long
- 特定の式に対して間違った型のリテラルを誤って取得する可能性があります。
そのため、リテラルの型が(またはそれより大きい)L
ことを確認したいコンテキストで、代わりに指定する必要があります。long
次の 2 つの重要なケースが思い浮かびます。
オーバーロードの解決; 関数のオーバーロードが 2 つあり、1 つは forint
と 1 つは forで、小さい数値を渡す場合でもlong
確実に 1 つを呼び出したい場合は、リテラルを使用する必要があります。long
long
void foo(int);
void foo(long);
foo(1); // <-- will call the first overload
foo(1L); // <-- will call the second overload
foo(32768); // <-- may call the first or the second overload, depending
// from the specific platform
foo(32768L); // <-- will call the second overload
しかし、最も重要なことは、算術を行うときに驚きを避けることです。たとえば、次のような乗算を実行する場合:
int a;
...
long v=32767*a; // don't let the "long" fool you - 32767*a is evaluated as an int!
32767
はint
リテラル ( に収まるほど小さいためint
)、a
は であり、に代入している場合でもint
、結果は になります。計算がオーバーフローするほど大きい場合、これは問題になる可能性があります。リテラルを指定することで、確実に乗算を実行できます。int
long
a
long
long
long v=32767L*a; // now we are doing all the math with longs
(この問題は実際には、意図した「実際の除算」の動作を得るためにリテラルdouble
またはリテラルを指定する必要がある除算および FP リテラルでより頻繁に発生します)float
@chrisが示唆するように、「大きな」ビットシフトを行うと、(これと同じ種類の)より頻繁な状況が発生します。
long long mask=1<<53;
上記と同じ問題を提示します: 1
is an int
, 53
is an int
, 計算はint
s で実行され、オーバーフローが発生します (ただし、この特定のケースでは、まともなコンパイラは警告を発行します)。ここで、正しい形式は次のようになります。
long long mask=1LL<<53; // LL is the suffix for long long
あなたの特定のコードに来てください:奪うことにリスクはありませんL
。number
はすでに であるため、long
モジュロを実行する際に (「通常の算術変換」、§5 ¶10、および §4.5 に従って) に2
昇格されるため、ここでは違いはありません。long
L
それでも、多くの場合、「意図した型」のリテラルを保持することは悪い考えではありません。これにより、他のオペランドの型が何らかの理由でより狭い型に変更された場合でも、計算が引き続き行われることが保証されます。意図した方法です(モジュロの場合、違いはありません)。
整数リテラルの型は、その値を表すことができる表 6 の対応するリストの最初のものです。
