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 つを呼び出したい場合は、リテラルを使用する必要があります。longlong
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、結果は になります。計算がオーバーフローするほど大きい場合、これは問題になる可能性があります。リテラルを指定することで、確実に乗算を実行できます。intlongalonglong
long v=32767L*a; // now we are doing all the math with longs
(この問題は実際には、意図した「実際の除算」の動作を得るためにリテラルdoubleまたはリテラルを指定する必要がある除算および FP リテラルでより頻繁に発生します)float
@chrisが示唆するように、「大きな」ビットシフトを行うと、(これと同じ種類の)より頻繁な状況が発生します。
long long mask=1<<53;
上記と同じ問題を提示します: 1is an int, 53is an int, 計算はints で実行され、オーバーフローが発生します (ただし、この特定のケースでは、まともなコンパイラは警告を発行します)。ここで、正しい形式は次のようになります。
long long mask=1LL<<53; // LL is the suffix for long long
あなたの特定のコードに来てください:奪うことにリスクはありませんL。numberはすでに であるため、longモジュロを実行する際に (「通常の算術変換」、§5 ¶10、および §4.5 に従って) に2昇格されるため、ここでは違いはありません。longL
それでも、多くの場合、「意図した型」のリテラルを保持することは悪い考えではありません。これにより、他のオペランドの型が何らかの理由でより狭い型に変更された場合でも、計算が引き続き行われることが保証されます。意図した方法です(モジュロの場合、違いはありません)。
整数リテラルの型は、その値を表すことができる表 6 の対応するリストの最初のものです。
