Episode ini mengupas apa yang terjadi di balik layar: proses kompilasi empat tahap, model memori C yang membagi stack, heap, static data, dan text segment, serta ABI dan calling convention. Kalian juga akan melihat struktur program C dan alur toolchain.

Sebuah program C tidak langsung menjadi executable. Ada seluruh pipeline yang bekerja di balik layar, mulai dari preprocessing sampai linking. Memahami pipeline ini membuat kalian bisa mendiagnosis error compiler, membaca pesan linker, dan mengoptimalkan ukuran binary.
Episode 2 membedah arsitektur internal bahasa C: empat tahap kompilasi, model memori yang membagi ruang alamat menjadi segmen berbeda, ABI dan calling convention yang menghubungkan fungsi-fungsi, serta struktur program dan toolchain yang menyusun semuanya.
Setelah episode ini, kalian tidak akan lagi melihat kode C sebagai teks biasa, melainkan sebagai blueprint yang melalui mesin transformasi presisi.
Tahap pertama membaca direktif yang diawali tanda #. Preprocessor mengganti #include dengan isi header, memperluas macro #define, dan menyaring bagian #ifdef. Hasilnya adalah file dengan semua include sudah ter-ekspansi. Jalankan tahap ini sendiri dengan:
gcc -E program.c -o program.i
wc -l program.iPerintah gcc -E program.c -o program.i menghasilkan file sementara yang jauh lebih panjang dari sumber aslinya, karena berisi seluruh isi header yang di-include.
Tahap kedua menerjemahkan C menjadi assembly spesifik arsitektur, lalu tahap ketiga menerjemahkan assembly menjadi object file berupa kode mesin. Object file belum bisa dijalankan karena referensi ke fungsi dari file lain masih kosong:
gcc -S program.c
gcc -c program.c -o program.o
file program.oBendera -S menghasilkan file .s berisi assembly, sedangkan -c menghasilkan object file .o. Untuk melihat simbol yang terdefinisi di dalam object file, gunakan nm:
nm program.oOutput nm program.o menunjukkan simbol seperti main dan fungsi library yang masih bersifat undefinisi.
Tahap terakhir adalah linking: linker menggabungkan semua object file, menyelesaikan referensi antar fungsi, dan menempelkan runtime library seperti libc. Hasilnya adalah executable:
gcc program.o -o program
readelf -h programreadelf -h program menampilkan header ELF, termasuk arsitektur, jenis file, dan entry point. Dari empat tahap di atas, hanya dua tahap pertama yang sering terlihat oleh programmer; error yang muncul di tahap linking biasanya berbunyi undefined reference.
Ketika sebuah executable dimuat, sistem operasi membagi memori proses menjadi beberapa segmen:
malloc, dikelola manual oleh programmer.Variabel global hidup sepanjang program, variabel lokal hidup hanya selama fungsi dipanggil, dan data heap hidup sampai dipanggil free.
size programPerintah size program menampilkan ukuran text, data, dan bss segmen secara sekilas. Ini cara cepat untuk memeriksa jejak memori sebuah program.
ABI atau Application Binary Interface adalah kontrak tingkat binary: ukuran tipe data, tata letak struct, dan cara fungsi dipanggil. Calling convention adalah bagian dari ABI yang menentukan bagaimana argumen dikirim ke fungsi — lewat register mana, dan bagaimana nilai dikembalikan.
Pada x86_64 Linux, konvensi System V menempatkan argumen pertama di register rdi, kedua di rsi, dan seterusnya. Program yang mengikuti ABI yang sama bisa saling terhubung meski ditulis di file berbeda. Ini yang memungkinkan fungsi printf dari libc dipanggil dari kode kalian.
Memahami ABI membantu kalian membaca error seperti undefined reference, memahami kenapa struct perlu disejajarkan (episode 17), dan mengapa library binary harus dibangun dengan ABI yang kompatibel. Ketidakcocokan ABI adalah penyebab klasik crash saat menautkan library yang di-compile dengan compiler berbeda.
Sebuah project C yang sehat terdiri dari beberapa komponen: file header yang mendeklarasikan antarmuka, file sumber yang mengimplementasikan, dan satu fungsi main sebagai titik masuk. Direktif preprocessor seperti #include dan #define memegang kendali, sedangkan linker menyatukan semuanya dengan library static atau shared.
Toolchain dasar bekerja dalam satu alur: edit di editor, kompilasi dengan gcc atau clang, link, lalu jalankan. Jika terjadi crash, debugger seperti gdb membaca core file dan stack untuk menemukan penyebab. Episode 11 akan membahas debugging mendalam, tetapi alurnya selalu dimulai dari pemahaman pipeline di atas.
Tip
Kebiasaan yang baik: kompilasi dengan gcc -Wall -Wextra -g. Dua bendera pertama menyalakan peringatan, dan -g menyimpan informasi debug yang dibutuhkan gdb dan valgrind.
Inti yang harus dibawa pulang:
-E, -S, -c, dan link penuh memisahkan setiap tahap pipeline.undefined reference muncul di tahap linking, bukan kompilasi.Di episode 3 selanjutnya kita akan membahas sintaks dasar dan struktur program C — deklarasi variabel dan tipe data dasar, fungsi main, statement, blok kode, komentar, hingga menyusun dan menjalankan program sederhana.