Standar C tidak menentukan ukuran pasti tipe int, long, dan long long dalam byte. Yang dijamin hanyalah urutan: short lebih kecil atau sama dengan int, dan int lebih kecil atau sama dengan long. Untuk memenuhi kebutuhan program yang spesifik—hemat memori pada perangkat kecil, atau menampung angka raksasa—C menyediakan modifier short, long, dan long long. Pada Chapter ini kita akan memetakan ukuran aktual di platform modern, kapan memakai masing-masing, dan kenapa tipe fixed-width seperti int32_t sering menjadi pilihan yang lebih aman.

Hierarki Ukuran Integer #

Standar C (ISO/IEC 9899:2017 bagian 5.2.4.2) menetapkan batas minimum, tetapi ukuran aktual bergantung pada ABI platform. Pada x86_64 Linux dengan GCC, ukuran yang umum adalah:

TipeUkuran (byte)Rentang minimum standar
short2-32.768 sampai 32.767
int4-32.768 sampai 32.767 (jaminan minimum)
long8 (Linux/macOS) / 4 (Windows)-2.147.483.648 sampai 2.147.483.647
long long8-9.223.372.036.854.775.808 sampai 9.223.372.036.854.775.807

Perhatikan bahwa long di Windows ukurannya 4 byte (model LLP64), sedangkan di Linux/macOS ukurannya 8 byte (model LP64). Inilah salah satu sumber bug klasik ketika kode C dipindahkan antar sistem operasi.

c
#include <stdio.h>
#include <limits.h>

int main(void) {
    short s = 1000;
    int i = 1000000;
    long l = 100000000L;
    long long ll = 9000000000LL;

    printf("short      = %hd\n", s);
    printf("int        = %d\n", i);
    printf("long       = %ld\n", l);
    printf("long long  = %lld\n", ll);

    printf("Ukuran short     = %zu byte\n", sizeof(short));
    printf("Ukuran int       = %zu byte\n", sizeof(int));
    printf("Ukuran long      = %zu byte\n", sizeof(long));
    printf("Ukuran long long = %zu byte\n", sizeof(long long));

    printf("SHRT_MAX  = %hd\n", SHRT_MAX);
    printf("INT_MAX   = %d\n", INT_MAX);
    printf("LONG_MAX  = %ld\n", LONG_MAX);
    printf("LLONG_MAX = %lld\n", LLONG_MAX);
    return 0;
}

Output yang Dihasilkan:

text
short      = 1000
int        = 1000000
long       = 100000000
long long  = 9000000000
Ukuran short     = 2 byte
Ukuran int       = 4 byte
Ukuran long      = 8 byte
Ukuran long long = 8 byte
SHRT_MAX  = 32767
INT_MAX   = 2147483647
LONG_MAX  = 9223372036854775807
LLONG_MAX = 9223372036854775807

Mari kita telaah baris-baris kode di atas:

  1. Baris 6 (short s = 1000;): short dijamin minimal 16 bit; di x86_64 GCC tetap 2 byte.
  2. Baris 8 (long l = 100000000L;): suffix L menandakan literal bertipe long; tanpa suffix, literal 100000000 masih muat di int sehingga tidak menjadi masalah, tetapi L membuat intensi eksplisit.
  3. Baris 9 (long long ll = 9000000000LL;): suffix LL wajib karena nilai 9.000.000.000 melebihi INT_MAX (2.147.483.647).
  4. Baris 11 (%hd): specifier untuk short (half-decimal); %d sendiri juga bisa dipakai karena integer promotion mengubah short menjadi int saat dilewatkan ke printf.
  5. Baris 13-14 (%ld, %lld): specifier khusus untuk long dan long long.
  6. Baris 22 (LLONG_MAX): konstanta dari limits.h yang menyatakan batas atas long long; nilainya 2^63 - 1.

Kapan Memakai long long #

Tipe long long diperkenalkan di C99 dan menjamin ukuran minimal 64 bit. Tipe ini wajib dipakai ketika nilai yang ditampung bisa melebihi INT_MAX (2.147.483.647). Contoh klasik adalah jumlah penduduk dunia (~7.9 miliar), transaksi finansial besar (dalam satuan rupiah), atau hasil perkalian dua angka yang masing-masing sudah besar.

c
#include <stdio.h>
#include <limits.h>

int main(void) {
    /* Kasus yang membutuhkan long long */
    long long penduduk_dunia = 7900000000LL;     /* 7.9 miliar */
    long long jarak_bulan_km = 384400LL;         /* jarak Bumi-Bulan */
    long long hasil = penduduk_dunia * 2;

    printf("Penduduk dunia  = %lld\n", penduduk_dunia);
    printf("Jarak Bumi-Bulan = %lld km\n", jarak_bulan_km);
    printf("Penduduk x2     = %lld\n", hasil);

    /* Mengapa int tidak cukup? */
    int attempt = (int)penduduk_dunia;     /* truncate */
    printf("Cast ke int     = %d (overflow!)\n", attempt);
    return 0;
}

Output yang Dihasilkan:

text
Penduduk dunia  = 7900000000
Jarak Bumi-Bulan = 384400 km
Penduduk x2     = 15800000000
Cast ke int     = -689934592 (overflow!)

Pada baris 7, nilai 7.900.000.000 melebihi INT_MAX (2.147.483.647), sehingga long long wajib dipakai. Pada baris 9, perkalian penduduk_dunia * 2 menghasilkan 15.800.000.000 yang juga masih muat di long long. Pada baris 14, cast (int)penduduk_dunia memotong 32 bit teratas sehingga sisanya diinterpretasikan sebagai int bertanda—hasilnya -689.934.592 yang jelas salah. Ini menunjukkan bahaya mengubah tipe yang lebih besar ke tipe yang lebih kecil.

Tipe Fixed-Width dari stdint.h #

Karena ukuran int dan long tidak konsisten antar platform, C99 memperkenalkan header <stdint.h> yang menyediakan tipe fixed-width: int8_t, int16_t, int32_t, int64_t, serta versi unsigned-nya (uint8_t dst). Tipe-tipe ini menjamin ukuran tepat, bukan minimal. Untuk menampilkan tipe-tipe ini dengan printf, gunakan makro PRId16, PRId32, PRId64 dari header <inttypes.h> agar portable di semua platform.

c
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main(void) {
    /* Tipe fixed-width dari <stdint.h> */
    int16_t a = 32000;
    int32_t b = 2000000000;
    int64_t c = 9000000000LL;
    uint8_t byte_val = 250;

    printf("int16_t  = %" PRId16 "\n", a);
    printf("int32_t  = %" PRId32 "\n", b);
    printf("int64_t  = %" PRId64 "\n", c);
    printf("uint8_t  = %" PRIu8 "\n", byte_val);

    printf("Ukuran int16_t = %zu byte\n", sizeof(int16_t));
    printf("Ukuran int64_t = %zu byte\n", sizeof(int64_t));
    return 0;
}

Output yang Dihasilkan:

text
int16_t  = 32000
int32_t  = 2000000000
int64_t  = 9000000000
uint8_t  = 250
Ukuran int16_t = 2 byte
Ukuran int64_t = 8 byte

Pada baris 11, makro PRId16 direntangkan oleh preprocessor menjadi format specifier yang tepat untuk int16_t di platform saat ini—misalnya "hd" di platform yang short 16 bit, atau "d" jika int 16 bit. Pendekatan ini menghindari bug format specifier yang muncul saat kode dipindahkan antar platform.

short untuk Hemat Memori #

Tipe short (2 byte) jarang dipakai pada kode desktop modern karena penghematan memorinya tidak signifikan. Tipe ini lebih sering muncul pada embedded system dengan RAM terbatas, atau pada format file biner yang spesifik mendefinisikan field 16-bit (misalnya format WAV atau PNG). Untuk komputasi biasa, int biasanya sama cepatnya dengan short karena prosesor modern dioptimalkan untuk operasi 32-bit.

Dengan modifier short, long, dan long long, kita punya fleksibilitas memilih ukuran tipe. Selanjutnya, kita akan belajar cara memeriksa ukuran tipe secara programatik menggunakan operator sizeof dan tipe size_t.