GCC dan Clang menerima ratusan command-line flag yang mengontrol standar bahasa, warning, optimasi, debugging, linking, dan analisis statis. Mengetahui flag yang paling sering dipakai akan membuat kita lebih produktif dan kode yang dihasilkan lebih aman. Bab ini menyusun flag GCC/Clang yang paling sering kita pakai, lengkap dengan contoh pemakaian dan dampaknya pada binary yang dihasilkan.

Flag Standar Bahasa #

Flag -std memilih versi standar C yang dipakai compiler untuk menginterpretasikan source code.

FlagEfek
-std=c89 / -std=c90Standar ISO C90 (ANSI C89)
-std=c99Standar ISO C99
-std=c11Standar ISO C11 (default GCC 14+)
-std=c17 / -std=c18Standar ISO C17 (bugfix C11)
-std=c2x / -std=c23Standar ISO C23 (GCC 15+)
-std=gnu11C11 + ekstensi GNU (default GCC)
-pedanticTolak ekstensi non-standar, hanya warning
-pedantic-errorsEkstensi non-standar jadi error

Flag Warning #

FlagEfek
-WallWarning umum (sign conversion tidak, unused var ya)
-WextraWarning tambahan (parameter tidak terpakai, signed/unsigned)
-WpedanticPeringati penggunaan ekstensi non-standar
-WerrorPerlakukan warning sebagai error
-WconversionKonversi implicit yang mungkin mengubah nilai
-WshadowVariabel lokal menutupi variabel luar
-Wformat=2Periksa format string printf/scanf ketat
-Wnull-dereferenceDeteksi dereference NULL
-WuninitializedVariabel dipakai sebelum diinisialisasi
-Wstrict-prototypesWajibkan void pada fungsi tanpa parameter
-Wunused-but-set-variableVariabel diset tapi tidak dibaca
-fanalyzerAnalisis statik ekstra (use-after-free, double-free)

Flag Optimasi #

FlagEfek
-O0Tidak ada optimasi (default, cepat compile, mudah debug)
-O1Optimasi ringan
-O2Optimasi standar (produksi, tidak termasuk space-speed tradeoff)
-O3Optimasi agresif (inline, vectorize)
-OsOptimasi untuk ukuran binary
-OzOptimasi ukuran lebih agresif (Clang)
-Ofast-O3 + math assumption (non-standar, mungkin mengubah float result)
-OgOptimasi ramah debug (GCC 4.8+)
-fltoLink-time optimization (LTO)

Flag Debug #

FlagEfek
-gSertakan simbol debug (DWARF)
-g3Lebih banyak informasi (macro expansion)
-ggdbFormat debug optimal untuk GDB
-p / -pgInstrument untuk gprof

Flag Include, Library, dan Linking #

FlagEfek
-I<path>Tambah path pencarian header
-L<path>Tambah path pencarian library
-l<name>Link dengan library lib<name>.{a,so}
-staticLink statik penuh
-sharedBuat shared object (library)
-fPICPosition-Independent Code (wajib untuk shared library)
-fPIEPosition-Independent Executable (default modern)
-pieHasilkan PIE executable
-Wl,<opt>Teruskan opsi ke linker
-Wl,-rpath,<path>Set runtime library search path
-Wl,--gc-sectionsBuang section yang tidak terpakai

Flag Sanitizer #

Sanitizer adalah tool bawaan GCC/Clang yang menginstrumentasi binary untuk mendeteksi bug memori dan UB saat runtime. Sangat berguna untuk testing.

FlagDeteksi
-fsanitize=addressBuffer overflow, use-after-free, double-free (ASan)
-fsanitize=undefinedSigned overflow, shift, null deref, alignment (UBSan)
-fsanitize=threadRace condition (TSan)
-fsanitize=memoryPenggunaan memori belum diinisialisasi (MSan, Clang only)
-fsanitize=leakMemory leak (LSan, terintegrasi ASan)
-fsanitize=address,undefinedKombinasi ASan + UBSan (paling sering dipakai)

Program Lengkap #

Program kecil berikut akan kita compile dengan berbagai kombinasi flag untuk melihat dampaknya pada binary dan output.

c
/* File: cflags1.c - Demo compiler flags */
#include <stdio.h>

int main(int argc, char *argv[]) {
    if (argc < 2) {
        fprintf(stderr, "Pemakaian: %s <nama>\n", argv[0]);
        return 1;
    }
    printf("Halo, %s!\n", argv[1]);
    return 0;
}

Compile dengan tiga profil berbeda dan amati hasilnya:

bash
# Profil 1: Optimasi produksi
gcc -std=c11 -Wall -Wextra -O2 -g -o cflags1_opt cflags1.c
./cflags1_opt Budi

# Profil 2: Strict dengan analisis statik
gcc -std=c11 -Wall -Wextra -Wpedantic -Wconversion -fanalyzer -o cflags1_strict cflags1.c
./cflags1_strict Budi

# Profil 3: Sanitizer untuk testing
gcc -std=c11 -Wall -Wextra -fsanitize=address,undefined -g -o cflags1_san cflags1.c
./cflags1_san Budi

# Periksa ukuran binary
ls -la cflags1_opt cflags1_strict cflags1_san

Output yang Dihasilkan (semua profil memberi output yang sama):

text
Halo, Budi!

Output ukuran binary dan debug info (ls -la dan file):

text
-rwxrwxr-x 18824 cflags1_opt    (optimized, with debug info)
-rwxrwxr-x 16032 cflags1_strict (no -O, no sanitizer)
-rwxrwxr-x 28696 cflags1_san     (ASan + UBSan, debug info)

cflags1_opt:    ELF 64-bit LSB pie executable, x86-64, with debug_info, not stripped
cflags1_strict: ELF 64-bit LSB pie executable, x86-64, not stripped
cflags1_san:    ELF 64-bit LSB pie executable, x86-64, with debug_info, not stripped

Mari kita telaah baris-baris kode di atas:

  1. Profil 1 (-O2 -g): Kombinasi optimasi standar dan debug info. Binary berukuran 18.824 byte—cukup kecil dan cepat. -g menyertakan simbol DWARF yang membantu gdb menampilkan nomor baris asli saat debugging.
  2. Profil 2 (-Wpedantic -Wconversion -fanalyzer): Tidak ada optimasi, tetapi warning ketat diaktifkan. Binary 16.032 byte (paling kecil) karena tanpa instrumentasi dan tanpa optimasi agresif yang menambah inline.
  3. Profil 3 (-fsanitize=address,undefined): Binary 28.696 byte (paling besar) karena ASan menambahkan shadow memory dan checks pada setiap akses memori. Inilah harga yang kita bayar untuk deteksi bug otomatis saat runtime.
  4. Output yang sama: Ketiga binary menghasilkan teks identik karena kode programnya valid dan tidak memicu bug. Jika kode memiliki bug memori, hanya cflags1_san yang akan memberikan pesan error.

Strategi Pemilihan Flag #

SkenarioFlag disarankan
Belajar / eksperimen-std=c11 -Wall -Wextra -g
Testing aktif cari bug-std=c11 -Wall -Wextra -g -O1 -fsanitize=address,undefined
Debug production issue-std=c11 -g -O2 -fno-omit-frame-pointer
Build produksi-std=c11 -O2 -Wall -Wextra -Werror -DNDEBUG
Build library sharedtambah -fPIC -shared
Build untuk profiling-std=c11 -g -O2 -pg