Kita sudah memasang compiler, memilih IDE, dan menulis program contoh — kini saatnya menguasai satu perintah yang menjalankan semuanya: perintah kompilasi. Perintah g++ kelihatannya sepele, tetapi di baliknya ada banyak pilihan yang menentukan versi standar yang dipakai, seberapa ketat compiler memeriksa kode, dan seberapa cepat program hasilnya berjalan. Mengenal flag-flag ini sejak awal akan menghemat waktu Anda setiap hari, karena banyak bug yang bisa ditangkap flag pada fase kompilasi, jauh sebelum program berjalan. Pada Chapter ini kita bedah anatomi perintah g++, mencoba flag-flag paling penting langsung di lingkungan praktikum, dan menutup dengan sekilas kompilasi program yang terdiri dari beberapa file.
Anatomi Perintah g++ #
Bentuk umum perintah kompilasi kita adalah: g++ [flag] nama-file.cpp -o nama-program. Tiga bagiannya: g++ adalah program yang dipanggil, flag di tengah mengubah perilaku compiler, dan -o nama-program memberi nama file hasil. Program contoh untuk Chapter ini adalah kalkulator kecil yang mencetak tabel perkalian:
#include <iostream>
int main() {
std::cout << "Program uji flag kompilasi\n";
for (int i = 1; i <= 5; ++i) {
std::cout << i << " x 7 = " << i * 7 << "\n";
}
return 0;
}Output yang Dihasilkan:
Program uji flag kompilasi
1 x 7 = 7
2 x 7 = 14
3 x 7 = 21
4 x 7 = 28
5 x 7 = 35Kompilasi dan jalankan dengan dua perintah berikut, dan perhatikan bahwa kompilasi yang sukses tidak mencetak apa pun:
g++ -std=c++23 -Wall -Wextra demo-flag.cpp -o demo-flag
./demo-flagApa yang terjadi bila kita lupa memberi flag -o? Compiler tidak menolak perintah itu — ia memakai nama bawaan a.out, kebiasaan warisan Unix:
g++ -std=c++23 demo-flag.cpp
ls a.outa.outKarena itu, biasakan selalu menulis -o dengan nama yang bermakna; nama a.out yang tertimpa terus-menerus oleh program berbeda hanya menyulitkan Anda sendiri.
Flag Penting yang Wajib Dikenal #
Tabel berikut merangkum flag yang akan kita pakai sepanjang course. Dua yang pertama muncul di hampir semua contoh course ini:
| Flag | Fungsi |
|---|---|
-std=c++23 | Memilih versi standar bahasa: c++17, c++20, atau c++23 |
-Wall -Wextra | Mengaktifkan peringatan (warning) untuk kode yang mencurigakan |
-g | Menyisipkan informasi debugging untuk gdb dan debugger IDE |
-O0 / -O2 | Level optimasi: tanpa optimasi (default) versus optimasi standar |
-o nama | Menentukan nama file hasil kompilasi |
-c | Kompilasi saja tanpa linking (menghasilkan object file) |
Flag -std kita sentuh tuntas pada Chapter Memilih Standar C++, jadi di sini cukup dua catatan praktis. Flag -g harus ada bila Anda ingin menjalankan debugger dari Chapter Menggunakan IDE dan Editor — breakpoint-nya bekerja, tetapi tanpa -g debugger tidak bisa menampilkan nama variabel dan baris source code. Adapun -O0 dan -O2 mengatur seberapa keras compiler mengoptimasi: -O0 mempertahankan kode persis seperti yang Anda tulis (paling ramah untuk debugging), sedangkan -O2 mengaktifkan optimasi standar untuk program yang siap dipakai — perbedaan ukuran assembly-nya sudah kita buktikan pada Chapter Memilih Compiler. Rincian lengkap kedua keluarga flag ini ada di dokumentasi resmi Warning Options GCC
dan Optimize Options GCC
.
Error vs Warning: Dua Kelas Pesan Compiler #
Pesan compiler terbagi dua kelas yang berbeda nasib. Error melanggar aturan bahasa sehingga compiler menyerah dan tidak menghasilkan program. Warning adalah kode yang sah menurut aturan, tetapi sangat diduga salah — compiler memperingatkan, lalu tetap melanjutkan. Contoh error nyata: salah ketik coutt pada program ini:
#include <iostream>
int main() {
std::coutt << "Halo\n";
return 0;
}Kompilasi program di atas menghasilkan pesan berikut — perhatikan GCC bahkan menawarkan perbaikannya:
demo-error.cpp: In function ‘int main()’:
demo-error.cpp:4:10: error: ‘coutt’ is not a member of ‘std’; did you mean ‘cout’?
4 | std::coutt << "Halo\n";
| ^~~~~
| coutBandingkan dengan contoh warning: program sah yang memiliki variabel yang tidak pernah dipakai:
#include <iostream>
int main() {
int sisa = 10;
std::cout << "Program berjalan\n";
return 0;
}Kompilasi dengan -Wall -Wextra menghasilkan peringatan, tetapi file hasil tetap dibuat:
demo-warning.cpp: In function ‘int main()’:
demo-warning.cpp:4:9: warning: unused variable ‘sisa’ [-Wunused-variable]
4 | int sisa = 10;
| ^~~~Variabel sisa dideklarasikan dan diisi, tetapi tidak pernah dibaca — hampir pasti bekas refactoring atau lupa logika. Warning semacam ini menandai bug yang belum terlihat pada uji coba, dan itulah alasan course ini selalu mengompilasi dengan -Wall -Wextra: tanpa flag itu, GCC menyembunyikan peringatan yang justru paling berguna bagi pemula.
Exit Code Kompilasi #
Setiap perintah di terminal meninggalkan jejak berupa exit code — angka status yang tersimpan di variabel $? shell. Konvensinya 0 berarti sukses dan selain nol berarti gagal. Perintah kompilasi mematuhi konvensi ini, dan kita bisa membuktikannya langsung:
g++ -std=c++23 demo-flag.cpp -o demo-flag
echo $?0Bandingkan dengan exit code setelah mencoba mengompilasi file demo-error.cpp yang salah tadi:
g++ -std=c++23 demo-error.cpp -o demo-error
echo $?1Angka ini bukan sekadar keriting terminal: build system, editor, dan pipeline CI membaca exit code untuk memutuskan apakah langkah berikutnya boleh berlanjut. Compiler yang gagal tidak pernah menghasilkan executable baru — file lama dengan nama yang sama tetap ada, sesuatu yang perlu Anda ingat saat program “tidak berubah-ubah” meski kode sudah diedit.
Kompilasi Multi-File Sekilas #
Sejauh ini semua contoh kita satu file. Program nyata terdiri dari banyak file, dan g++ menerimanya dengan mencantumkan semua file sumber dalam satu perintah. Misalnya program kecil yang memisahkan deklarasi dan implementasi fungsi luas ke dalam file tersendiri:
double luasPersegiPanjang(double panjang, double lebar);#include "geo.h"
double luasPersegiPanjang(double panjang, double lebar) {
return panjang * lebar;
}#include <iostream>
#include "geo.h"
int main() {
std::cout << "Luas kamar 4 x 3 = " << luasPersegiPanjang(4.0, 3.0) << "\n";
return 0;
}Tiga file di atas (simpan sebagai geo.h, geo.cpp, dan utama.cpp) sudah kami uji di lingkungan praktikum. Kompilasinya mencantumkan kedua file .cpp, dan hasilnya:
g++ -std=c++23 -Wall -Wextra utama.cpp geo.cpp -o utama
./utamaLuas kamar 4 x 3 = 12Catatan penting: hanya file .cpp yang dicantumkan — file geo.h tidak, karena header dimasukkan lewat #include, bukan dikompilasi langsung. Bila proyek tumbuh menjadi belasan file, mengetik ulang semua nama setiap kali diedit melelahkan; flag -c (kompilasi per-file menjadi object file) plus tool bernama make yang menyelesaikan masalah itu akan kita bahas pada Section Build System dan Project Structure.
Dengan perintah g++ yang kini Anda kuasai, satu pertanyaan besar masih menggantung: apa sebenarnya yang terjadi di dalamnya? Chapter berikutnya membuka kap mesin itu — empat tahap preprocessor, compiler, assembler, dan linker — lengkap dengan demonstrasi nyata setiap tahapnya.