質問: C言語の参考書では、整数リテラルの最後に「L」を付けるとlong型になると説明されています。 確かにメモリ上のサイズは「1」と「1L」で違っていました。 ※sizeof(1)は4、sizeof(1L)は8でした。 ### 質問 メモリ上のサイズの他に「1」と「1L」で違いはあるのでしょうか? 「1」と「1L」で演算結果が異なるケースや呼び出した関数の振る舞いが異なるケースが知りたいです。
回答: 整数リテラルの型が変わることによる影響はいくつかあります。分かりやすいのは、リテラル同士を演算してオーバーフローする場合でしょう。 `100000000`(1 億)は 32bit signed int の範囲ですが、その 2 乗は 32bit signed int の範囲を超え、64bit signed int の範囲に入ります。このため 32bit signed int として 2 乗を行うと、結果も 32bit signed int として格納され、オーバーフローします。 ``` #include int main(void) { printf("%ld\n", (long)(100000000 * 100000000)); /* オーバーフローします */ printf("%ld\n", 100000000L * 100000000L); /* 10000000000000000 が出力されます */ return 0; } ``` (Wandbox) 他にも、上のプログラムでも不自然に long にキャストしている理由でもありますが、`printf("%ld", 1);` の挙動は未定義な一方 `printf("%ld", 1L);` は正しく 1 を出力するという違いも生まれています。 また、`L` だけだと使いどころが分かりづらいですが、整数リテラルの末尾記号には他にも `UL` などがあり、それらと組み合わせると他にも使いどころが生まれてきます。詳しくは what is the reason for explicitly declaring L or UL for long values をご覧ください。