GCC (GNU Compiler Collection) e Clang (frontend LLVM) sono i due principali compilatori C/C++ open-source. Condividono la quasi totalità delle flag da riga di comando: nella maggior parte dei casi, basta sostituire gcc con clang (o g++ con clang++).
# Compilare ed eseguire un file C gcc main.c -o prog clang main.c -o prog # Compilare C++ g++ main.cpp -o prog clang++ main.cpp -o prog # Multifile gcc main.c utils.c io.c -o prog # Compilazione separata (object files + linking) gcc -c main.c # produce main.o gcc -c utils.c # produce utils.o gcc main.o utils.o -o prog # linking
| Flag | Descrizione |
|---|---|
-o <file> | Nome del file di output |
-c | Solo compilazione (produce .o, no linking) |
-S | Produce assembly (.s) |
-E | Solo preprocessore (output su stdout) |
-v | Output verboso (mostra comandi interni) |
-### | Mostra comandi che verrebbero eseguiti (dry run) |
-pipe | Usa pipe tra le fasi invece di file temporanei |
-x <lang> | Forza il linguaggio (c, c++, objective-c) |
--version | Mostra versione del compilatore |
# Aggiungere directory di include gcc -I./include -I/usr/local/include main.c -o prog # Linkare librerie gcc main.c -L/usr/local/lib -lm -lpthread -o prog # Include di sistema vs. locali gcc -isystem /opt/sdk/include main.c # sopprime warning da queste header
gcc, ma sono intercambiabili con clang salvo dove indicato diversamente.| Flag | Standard |
|---|---|
-std=c89 / -std=c90 | ANSI C (ISO C90) |
-std=c99 | ISO C99 |
-std=c11 | ISO C11 |
-std=c17 | ISO C17 (bug-fix di C11) |
-std=c23 | ISO C23 (più recente) |
-std=gnu17 | C17 + estensioni GNU (default) |
| Flag | Standard |
|---|---|
-std=c++98 / -std=c++03 | C++98/03 |
-std=c++11 | C++11 |
-std=c++14 | C++14 |
-std=c++17 | C++17 |
-std=c++20 | C++20 |
-std=c++23 | C++23 |
-std=gnu++20 | C++20 + estensioni GNU |
# Conformità stretta (disabilita estensioni) gcc -std=c17 -pedantic main.c # Estensioni GNU esplicite gcc -std=gnu17 main.c # Modalità freestanding (no hosted environment) gcc -ffreestanding -nostdlib kernel.c -o kernel.bin
# Definire macro gcc -DDEBUG main.c # #define DEBUG 1 gcc -DVERSION=3 main.c # #define VERSION 3 gcc -DMSG='"hello"' main.c # #define MSG "hello" # Rimuovere macro predefinita gcc -UNDEBUG main.c
# Solo output preprocessato gcc -E main.c -o main.i # Visualizzare macro predefinite gcc -dM -E -x c /dev/null # Generare dipendenze per Makefile gcc -M main.c # tutte le dipendenze gcc -MM main.c # solo dipendenze non-sistema gcc -MMD main.c # compila E genera .d file
# GCC: generare e usare PCH gcc common.h # produce common.h.gch gcc main.c -o prog # usa common.h.gch automaticamente se #include "common.h" # Clang: generare e usare PCH (esplicito) clang -x c-header common.h -o common.h.pch clang -include-pch common.h.pch main.c -o prog
| Flag | Output | Descrizione |
|---|---|---|
-E | .i | Solo preprocessing |
-S | .s | Assembly testuale |
-c | .o | Object file (codice macchina) |
| (default) | eseguibile | Compilazione completa + linking |
# Generare LLVM IR leggibile clang -S -emit-llvm main.c -o main.ll # Generare LLVM bitcode clang -c -emit-llvm main.c -o main.bc # Convertire bitcode in IR leggibile llvm-dis main.bc -o main.ll # Compilare bitcode in object file llc main.bc -o main.o -filetype=obj
# Assembly con sintassi Intel (default è AT&T) gcc -S -masm=intel main.c -o main.s # Assembly con annotazioni sorgente gcc -S -g -fverbose-asm main.c -o main.s # GCC: generare RTL (rappresentazione interna GCC) gcc -fdump-rtl-expand main.c # produce main.c.*.expand
-E) → GIMPLE/RTL → ottimizzazione → assembly (-S) → object (-c) → linking → eseguibile.Pipeline Clang: sorgente → preprocessing (
-E) → LLVM IR (-emit-llvm) → ottimizzazione → assembly (-S) → object (-c) → linking → eseguibile.| Flag | Descrizione |
|---|---|
-l<lib> | Linka la libreria lib<lib>.so / .a |
-L<dir> | Aggiungi directory di ricerca librerie |
-static | Linking statico (nessuna dipendenza .so) |
-shared | Produce libreria condivisa (.so / .dylib) |
-fPIC | Position-Independent Code (per .so) |
-fPIE | Position-Independent Executable |
-nostdlib | Non linkare la libreria standard |
-nodefaultlibs | Non linkare le librerie di default |
-nostartfiles | Non usare i file di startup (crt0, crti) |
-Wl,<opt> | Passa opzione al linker |
-Wl,-rpath,<dir> | Imposta runtime library path |
| Flag | Linker | Note |
|---|---|---|
-fuse-ld=bfd | GNU ld (BFD) | Linker tradizionale GNU |
-fuse-ld=gold | GNU gold | Più veloce di BFD per ELF |
-fuse-ld=lld | LLVM lld | Il più veloce, specifico LLVM |
-fuse-ld=mold | mold | Linker moderno, estremamente veloce |
# Creare una libreria condivisa gcc -shared -fPIC utils.c -o libutils.so # Creare una libreria statica gcc -c utils.c ar rcs libutils.a utils.o # GNU ar (o llvm-ar) # Linkare contro la libreria gcc main.c -L. -lutils -Wl,-rpath,. -o prog # Versioning della libreria condivisa (soname) gcc -shared -fPIC -Wl,-soname,libutils.so.1 utils.c -o libutils.so.1.0
| Flag | Descrizione |
|---|---|
-g | Informazioni di debug standard (DWARF) |
-g0 | Nessuna info di debug |
-g1 | Info minimali (solo tabella simboli e backtrace) |
-g2 | Info di default (equivale a -g) |
-g3 | Info massime (include macro) |
-gline-tables-only | Solo tabelle di riga (minimo per profiling) |
-gdwarf-4 | Forza formato DWARF versione 4 |
-gdwarf-5 | Forza formato DWARF versione 5 |
-ggdb | Debug info ottimizzate per GDB GCC |
# Debug completo (disabilita ottimizzazioni per chiarezza) gcc -g -O0 main.c -o prog # Debug con ottimizzazioni (per profiling in release) gcc -g -O2 main.c -o prog # Split DWARF (debug info separate per linking più veloce) gcc -g -gsplit-dwarf main.c -o prog # produce anche main.dwo
Entrambi i compilatori offrono diagnostica dettagliata. Clang è noto per messaggi particolarmente chiari con suggerimenti fix-it e indicazione precisa della colonna. GCC ha migliorato la diagnostica nelle versioni recenti.
| Flag | Descrizione |
|---|---|
-Wall | Warning comuni (non tutti, ma i più utili) |
-Wextra | Warning aggiuntivi non inclusi in -Wall |
-Wpedantic | Avvisi per violazioni dello standard ISO |
-Werror | Tratta tutti i warning come errori |
-Werror=<w> | Solo il warning specifico diventa errore |
-Wno-<w> | Disabilita un warning specifico |
-w | Disabilita tutti i warning |
| Flag | Rileva |
|---|---|
-Wshadow | Variabile locale nasconde una esterna |
-Wconversion | Conversioni implicite con perdita di dati |
-Wsign-conversion | Conversioni signed/unsigned |
-Wfloat-equal | Confronti diretti tra float |
-Wformat=2 | Errori di formato printf/scanf (livello 2) |
-Wnull-dereference | Possibili dereference di puntatori nulli |
-Wdouble-promotion | Promozione implicita float → double |
-Wundef | Uso di macro non definite in #if |
-Wunused | Variabili, funzioni, parametri non usati |
-Wimplicit-fallthrough | Fallthrough non annotato in switch |
-Wmissing-prototypes | Funzioni senza prototipo dichiarato |
-Wstrict-overflow=<n> | Ottimizzazioni basate su assenza di overflow (livelli 1-5) |
| Flag | Compilatore | Descrizione |
|---|---|---|
-Weverything | CLANG | Abilita tutti i warning (utile per scoprirli) |
-Wlogical-op | GCC | Operazioni logiche sospette |
-Wduplicated-cond | GCC | Condizioni duplicate in if/else-if |
-Wduplicated-branches | GCC | Branch identici in if/else |
-Wrestrict | GCC | Violazione di restrict rilevate a compile-time |
-Wstringop-overflow | GCC | Buffer overflow in operazioni su stringhe |
# Setup raccomandato per sviluppo gcc -Wall -Wextra -Wpedantic -Wshadow -Wconversion main.c # Setup rigido GCC (CI/CD) gcc -Wall -Wextra -Werror -Wpedantic -Wlogical-op -Wduplicated-cond main.c # Setup rigido Clang (CI/CD) clang -Weverything -Wno-padded -Wno-disabled-macro-expansion -Werror main.c # Sopprimere un warning nel codice sorgente (GCC) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-variable" int x = 42; #pragma GCC diagnostic pop # Sopprimere un warning nel codice sorgente (Clang) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-variable" int x = 42; #pragma clang diagnostic pop
#pragma GCC diagnostic funziona anche con Clang (per compatibilità). Il #pragma clang diagnostic è specifico di Clang.I sanitizer sono strumenti di instrumentazione runtime che rilevano bug a tempo di esecuzione. Sviluppati originariamente per LLVM/Clang, sono disponibili anche in GCC. Le flag sono identiche.
# Rileva: buffer overflow, use-after-free, stack overflow, memory leak gcc -fsanitize=address -g -O1 main.c -o prog ./prog # Con rilevamento leak (abilitato di default su Linux) ASAN_OPTIONS=detect_leaks=1 ./prog # Opzioni utili ASAN_OPTIONS=halt_on_error=0:detect_stack_use_after_return=1 ./prog
# Rileva: signed overflow, null deref, shift errati, type punning gcc -fsanitize=undefined -g main.c -o prog # Sottogruppi specifici gcc -fsanitize=signed-integer-overflow,null,shift main.c # Combinare ASan + UBSan gcc -fsanitize=address,undefined -g -O1 main.c -o prog
# Rileva: lettura di memoria non inizializzata clang -fsanitize=memory -g -O1 -fno-omit-frame-pointer main.c -o prog # Con tracking dell'origine del valore non inizializzato clang -fsanitize=memory -fsanitize-memory-track-origins=2 -g main.c
# Rileva: data race, deadlock gcc -fsanitize=thread -g -O1 main.c -lpthread -o prog
| Combinazione | Compatibile? |
|---|---|
| ASan + UBSan | Sì |
| ASan + LeakSan | Sì (LeakSan è integrato in ASan) |
| ASan + MSan | No |
| ASan + TSan | No |
| MSan + TSan | No |
| UBSan + qualsiasi | Sì |
-g con i sanitizer per stack trace leggibili. -fno-omit-frame-pointer migliora i trace. MSan è disponibile solo in Clang e richiede che tutte le librerie collegate siano compilate con MSan. GCC supporta ASan, TSan e UBSan ma non MSan.Entrambi i compilatori offrono analisi statica integrata con approcci diversi: Clang usa --analyze / scan-build, GCC usa -fanalyzer (dalla versione 10).
# Analisi statica integrata (GCC 10+) gcc -fanalyzer main.c -o prog # Combinare con warning aggressivi gcc -fanalyzer -Wall -Wextra main.c # Disabilitare un warning specifico dell'analyzer gcc -fanalyzer -Wno-analyzer-double-free main.c
Rileva: use-after-free, double-free, null dereference, memory leak, buffer overflow, file descriptor leak, use-of-uninitialized-value. Vantaggio: integrato nel compilatore, nessun tool esterno necessario.
# Analisi statica su un singolo file clang --analyze main.c # Con output dettagliato clang --analyze -Xanalyzer -analyzer-output=text main.c # Abilitare checker specifici clang --analyze -Xanalyzer -analyzer-checker=core,deadcode,security main.c # Lista checker disponibili clang --analyze -Xanalyzer -analyzer-checker-help
# Analizzare un intero progetto basato su make scan-build make # Con report HTML scan-build -o ./report make # Specificare il compilatore scan-build --use-cc=clang --use-c++=clang++ make # Analizzare un progetto CMake scan-build cmake --build build/
| Checker | Rileva |
|---|---|
core | Null deref, divisione per zero, logica di base |
deadcode | Codice irraggiungibile |
security | Uso di API insicure, buffer overflow potenziali |
unix | Uso errato di API POSIX (malloc/free, file descriptor) |
cplusplus | Problemi specifici C++ (new/delete, iteratori) |
nullability | Violazioni di annotazioni nullable/nonnull |
| Flag | Descrizione | Disponibilità |
|---|---|---|
-O0 | Nessuna ottimizzazione (default). Compilazione veloce, debug facile | ENTRAMBI |
-O1 | Ottimizzazioni leggere. Buon compromesso compile-time / velocità | ENTRAMBI |
-O2 | Ottimizzazioni standard per release. Raccomandato per produzione | ENTRAMBI |
-O3 | Ottimizzazioni aggressive (vectorization, unrolling). Binario più grande | ENTRAMBI |
-Os | Ottimizza per dimensione del binario (come -O2 senza aumentare size) | ENTRAMBI |
-Og | Ottimizza per esperienza di debug (migliore di -O0, debuggabile) | GCC |
-Oz | Ottimizza aggressivamente per dimensione | CLANG |
-Ofast | Come -O3 + -ffast-math (può violare standard IEEE 754) | ENTRAMBI |
| Flag | Effetto |
|---|---|
-ffast-math | Ottimizzazioni floating-point aggressive (non safe) |
-fno-strict-aliasing | Disabilita strict aliasing (più sicuro con type punning) |
-funroll-loops | Srotola i loop |
-fvectorize | Abilita auto-vectorization (abilitato da -O2) |
-march=native | Ottimizza per la CPU corrente |
-mtune=<cpu> | Tuning per CPU specifica senza limitare istruzioni |
-fomit-frame-pointer | Libera un registro (può complicare il debug) |
-finline-functions | Abilita inlining aggressivo |
-flto | Link-Time Optimization (vedi sezione dedicata) |
# Clang: ottimizzazioni applicate clang -O2 -Rpass=. main.c -o prog # Clang: ottimizzazioni mancate clang -O2 -Rpass-missed=. main.c # Clang: solo vectorization clang -O2 -Rpass=loop-vectorize -Rpass-missed=loop-vectorize main.c # GCC: dump di tutte le ottimizzazioni applicate gcc -O2 -fopt-info-all main.c -o prog # GCC: solo vectorization gcc -O2 -fopt-info-vec-missed main.c # GCC: dump su file gcc -O2 -fopt-info-all=optim.log main.c
-Og è specifico GCC: ottimizza quanto possibile senza compromettere il debugging. Ideale per lo sviluppo quotidiano al posto di -O0. Clang lo accetta ma lo tratta come alias di -O1. -Oz è specifico Clang: utile per firmware e WebAssembly.LTO posticipa le ottimizzazioni alla fase di linking, permettendo ottimizzazioni inter-modulo (inlining tra file, eliminazione codice morto globale).
# Compilazione con Full LTO gcc -flto -O2 -c a.c gcc -flto -O2 -c b.c gcc -flto -O2 a.o b.o -o prog # In un solo comando gcc -flto -O2 a.c b.c -o prog # GCC: LTO parallelizzato gcc -flto=auto -O2 a.c b.c -o prog # usa tutti i core gcc -flto=4 -O2 a.c b.c -o prog # usa 4 core
# ThinLTO: più veloce di Full LTO, parallelizzabile clang -flto=thin -O2 a.c b.c -o prog # Con cache per build incrementali clang -flto=thin -O2 -Wl,-cache_path_lto,/tmp/lto-cache a.c b.c -o prog
| Aspetto | GCC Full LTO | GCC LTO (=auto) | Clang ThinLTO |
|---|---|---|---|
| Velocità compilazione | Lenta | Buona (parallela) | Veloce (parallela) |
| Qualità ottimizzazione | Massima | Massima | Molto vicina a Full |
| Uso memoria | Alto | Moderato | Moderato |
| Build incrementali | No | No | Sì (con cache) |
-flto=auto (richiede make -j per il link). ThinLTO è esclusivo di Clang/LLVM e raccomandato per grandi progetti.PGO usa dati di esecuzione reale per guidare le ottimizzazioni: branch prediction, layout del codice, inlining. Processo in 3 fasi. GCC e Clang hanno workflow diversi.
# Fase 1: compilare con instrumentazione gcc -fprofile-generate -O2 main.c -o prog.instr # Fase 2: eseguire con input rappresentativo ./prog.instr < typical_input.txt # genera file .gcda nella directory corrente # Fase 3: ricompilare con il profilo gcc -fprofile-use -O2 main.c -o prog.opt # Con correzione automatica per profili imprecisi gcc -fprofile-use -fprofile-correction -O2 main.c -o prog.opt
# Fase 1: compilare con instrumentazione clang -fprofile-instr-generate -O2 main.c -o prog.instr # Fase 2: eseguire con input rappresentativo ./prog.instr < typical_input.txt # genera default.profraw # Fase 2b: convertire il profilo (necessario per Clang) llvm-profdata merge -output=default.profdata default.profraw # Fase 3: ricompilare con il profilo clang -fprofile-instr-use=default.profdata -O2 main.c -o prog.opt
# Alternativa: profiling tramite perf (no instrumentazione, solo Linux) gcc -O2 -g main.c -o prog perf record -b ./prog # GCC: usare profilo AutoFDO create_gcov --binary=prog --profile=perf.data --gcov=profile.afdo gcc -fauto-profile=profile.afdo -O2 main.c -o prog.opt # Clang: usare profilo sampling llvm-profgen --binary=prog --output=perf.profdata --perfdata=perf.data clang -fprofile-sample-use=perf.profdata -O2 main.c -o prog.opt
llvm-profdata merge).# Compilare con profiling gcc -pg -O2 main.c -o prog # Eseguire (genera gmon.out) ./prog # Analizzare il profilo gprof prog gmon.out # report completo gprof -b prog gmon.out # report breve (senza spiegazioni) gprof -p prog gmon.out # solo flat profile gprof -q prog gmon.out # solo call graph
# Compilare con coverage gcc --coverage -O0 main.c -o prog # equivale a: gcc -fprofile-arcs -ftest-coverage main.c # Eseguire (genera .gcda) ./prog # Analizzare coverage gcov main.c # genera main.c.gcov gcov -b main.c # con info sui branch # Report HTML con lcov lcov --capture --directory . --output-file coverage.info genhtml coverage.info --output-directory report/
# Compilare con coverage clang -fprofile-instr-generate -fcoverage-mapping main.c -o prog # Eseguire ./prog # Convertire profilo e visualizzare llvm-profdata merge default.profraw -o default.profdata llvm-cov show prog -instr-profile=default.profdata # Report riassuntivo llvm-cov report prog -instr-profile=default.profdata # Esportare in HTML llvm-cov show prog -instr-profile=default.profdata -format=html -output-dir=report/
gprof richiede -pg a compile-time e produce overhead runtime. Per profiling più accurato su Linux, preferire perf (non richiede ricompilazione). gcov/lcov sono lo standard per coverage in CI con GCC.Clang è un cross-compiler nativo (un singolo binario per tutti i target). GCC richiede una toolchain separata per ogni target (es. aarch64-linux-gnu-gcc).
# Formato: <arch>-<vendor>-<os>-<abi> x86_64-unknown-linux-gnu # Linux x86_64 con glibc x86_64-unknown-linux-musl # Linux x86_64 con musl aarch64-unknown-linux-gnu # Linux ARM64 arm-none-eabi # Bare-metal ARM (embedded) riscv64-unknown-linux-gnu # Linux RISC-V 64-bit wasm32-unknown-wasi # WebAssembly (WASI) x86_64-apple-darwin # macOS x86_64 aarch64-apple-darwin # macOS ARM (Apple Silicon) x86_64-pc-windows-msvc # Windows MSVC ABI
# Cross-compilare per ARM64 Linux clang --target=aarch64-unknown-linux-gnu main.c -o prog # Con sysroot (header e librerie del target) clang --target=aarch64-unknown-linux-gnu --sysroot=/opt/sysroot/arm64 main.c # Per bare-metal ARM (embedded) clang --target=arm-none-eabi -ffreestanding -nostdlib startup.c -o firmware.elf # Per WebAssembly clang --target=wasm32-unknown-wasi --sysroot=/opt/wasi-sdk/share/wasi-sysroot main.c -o prog.wasm # Mostrare il target corrente clang -print-target-triple
# GCC richiede una toolchain per-target (installata separatamente) # Esempio: su Debian/Ubuntu sudo apt install gcc-aarch64-linux-gnu # Cross-compilare per ARM64 Linux aarch64-linux-gnu-gcc main.c -o prog # Per bare-metal ARM arm-none-eabi-gcc -ffreestanding -nostdlib startup.c -o firmware.elf # Mostrare il target configurato gcc -dumpmachine
# Lista CPU disponibili per un target gcc -march=native -Q --help=target # GCC llc -march=arm -mcpu=help # LLVM/Clang # Compilare per una CPU specifica gcc -march=armv7-a -mfloat-abi=hard -mfpu=neon main.c
Estensioni originariamente GCC, supportate anche da Clang per compatibilità. Attive di default con -std=gnu*; disabilitate con -std=c* + -pedantic.
| Attributo | Effetto |
|---|---|
__attribute__((packed)) | Rimuove padding da struct |
__attribute__((aligned(N))) | Allineamento a N byte |
__attribute__((unused)) | Sopprime warning per variabili/funzioni non usate |
__attribute__((deprecated("msg"))) | Marca come deprecato |
__attribute__((noreturn)) | La funzione non ritorna (es. exit) |
__attribute__((format(printf, M, N))) | Verifica formato printf all'argomento M, variadic a N |
__attribute__((constructor)) | Eseguita prima di main() |
__attribute__((destructor)) | Eseguita dopo main() (o a exit) |
__attribute__((visibility("hidden"))) | Simbolo non esportato dalla libreria condivisa |
__attribute__((weak)) | Simbolo weak (overridable al link) |
__attribute__((cleanup(fn))) | Chiama fn quando la variabile esce dallo scope |
__attribute__((section("name"))) | Piazza la variabile/funzione nella sezione ELF specificata |
| Builtin | Effetto |
|---|---|
__builtin_expect(expr, val) | Branch prediction hint (likely/unlikely) |
__builtin_unreachable() | Indica codice irraggiungibile (aiuta l'ottimizzatore) |
__builtin_clz(x) | Conta leading zeros |
__builtin_ctz(x) | Conta trailing zeros |
__builtin_popcount(x) | Conta bit a 1 |
__builtin_bswap32(x) | Byte swap 32-bit |
__builtin_prefetch(addr) | Prefetch in cache |
__builtin_types_compatible_p(T1, T2) | 1 se i tipi sono compatibili |
__builtin_offsetof(type, member) | Offset di un membro nella struct |
# typeof (pre-C23; in C23 è typeof standard) typeof(x) y = x; # Statement expression (blocco come espressione) #define MAX(a,b) ({ typeof(a) _a=(a); typeof(b) _b=(b); _a>_b?_a:_b; }) # Designated initializer range (GCC/Clang extension) int arr[100] = { [0 ... 9] = 1, [10 ... 99] = 2 }; # Case range in switch case 0 ... 9: /* gestisci cifre */ # Labels as values (computed goto) void *labels[] = { &&label_a, &&label_b }; goto *labels[idx];
typeof, [[deprecated]], [[noreturn]], _Static_assert senza messaggio. Preferire gli attributi standard [[...]] quando possibile.Entrambi gli ecosistemi forniscono strumenti equivalenti per manipolare binari, archivi e object file.
| Funzione | GNU (GCC) | LLVM (Clang) |
|---|---|---|
| Compilatore C | gcc | clang |
| Compilatore C++ | g++ | clang++ |
| Linker | ld / gold | lld |
| Archivi statici | ar | llvm-ar |
| Simboli | nm | llvm-nm |
| Disassemblatore | objdump | llvm-objdump |
| Header ELF | readelf | llvm-readelf |
| Strip simboli | strip | llvm-strip |
| Dimensioni sezioni | size | llvm-size |
| Stringhe nel binario | strings | llvm-strings |
| Copia object | objcopy | llvm-objcopy |
| Coverage | gcov | llvm-cov |
| Profiling | gprof | llvm-profdata |
| Formattazione | — | clang-format |
| Linter | — | clang-tidy |
# Formattare un file (output su stdout) clang-format main.c # Formattare in-place clang-format -i main.c # Con stile predefinito clang-format -style=google main.c # google, llvm, chromium, mozilla, webkit # Generare file di configurazione clang-format -style=llvm -dump-config > .clang-format # Formattare tutti i file C/C++ ricorsivamente find . -name '*.c' -o -name '*.h' | xargs clang-format -i
# Analisi con check di default clang-tidy main.c -- # Con check specifici clang-tidy -checks='bugprone-*,modernize-*,performance-*' main.cpp -- # Applicare fix automaticamente clang-tidy -checks='modernize-*' -fix main.cpp -- # Con compilation database (da CMake) cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON . clang-tidy -p build/ main.cpp
# Disassemblare un binario objdump -d prog # GNU llvm-objdump -d prog # LLVM # Con codice sorgente interleaved objdump -d -S prog # Elencare simboli nm prog # tutti i simboli nm -u prog # solo undefined (dipendenze esterne) # Strippare il binario per la release strip prog
| Aspetto | GCC | Clang/LLVM |
|---|---|---|
| Licenza | GPLv3 | Apache 2.0 con eccezione LLVM |
| Diagnostica | Buona (migliorata recentemente) | Eccellente (fix-it, indicazione colonna) |
| Velocità compilazione | Generalmente più lenta | Generalmente più veloce |
| Qualità codice generato | Spesso leggermente migliore | Molto simile, dipende dal caso |
| Cross-compilazione | Richiede toolchain per-target | Nativa (un binario per tutti i target) |
| Piattaforme forti | Linux, embedded, molte architetture | macOS, BSD, Android, WASM |
| Static analyzer | -fanalyzer (GCC 10+) | --analyze / scan-build |
| MSan | Non disponibile | Disponibile |
| Rappresentazione interna | GIMPLE/RTL | LLVM IR (ispezionabile con -emit-llvm) |
| Formattazione / Linting | — | clang-format, clang-tidy |
| Flag | Compilatore | Descrizione |
|---|---|---|
-Og | GCC | Ottimizzazione per debug (Clang lo tratta come -O1) |
-Oz | CLANG | Ottimizzazione aggressiva per dimensione |
-Weverything | CLANG | Abilita tutti i warning |
-Wlogical-op | GCC | Operazioni logiche sospette |
-Wduplicated-cond | GCC | Condizioni duplicate in if-else |
-fanalyzer | GCC | Static analyzer integrato |
--analyze | CLANG | Static analyzer |
-emit-llvm | CLANG | Output LLVM IR / bitcode |
-flto=thin | CLANG | ThinLTO |
-flto=auto | GCC | LTO parallelo automatico |
-pg | GCC | Profiling con gprof |
-fsanitize=memory | CLANG | MemorySanitizer |
-fsanitize=safe-stack | CLANG | Safe stack protection |
-fsanitize=cfi | CLANG | Control Flow Integrity |
-ggdb | GCC | Debug info ottimizzate per GDB |
| Flag | Protezione |
|---|---|
-fstack-protector-strong | Stack canary per funzioni a rischio |
-fstack-protector-all | Stack canary per tutte le funzioni |
-D_FORTIFY_SOURCE=2 | Check runtime su funzioni di libreria (memcpy, sprintf...) |
-D_FORTIFY_SOURCE=3 | Check più aggressivi (GCC 12+ / Clang 15+) |
-fPIE -pie | Position-Independent Executable (ASLR completo) |
-Wl,-z,relro,-z,now | Full RELRO (GOT read-only) |
-fcf-protection | Control-Flow Enforcement (Intel CET) |
-fstack-clash-protection | Protezione da stack clash attacks |
# GCC: build di produzione gcc -O2 -DNDEBUG -flto=auto \ -fstack-protector-strong -D_FORTIFY_SOURCE=2 \ -fPIE -pie -Wl,-z,relro,-z,now \ -fstack-clash-protection \ -Wall -Wextra -Werror \ main.c -o prog # Clang: build di produzione clang -O2 -DNDEBUG -flto=thin \ -fstack-protector-strong -D_FORTIFY_SOURCE=2 \ -fPIE -pie -Wl,-z,relro,-z,now \ -fsanitize=cfi -fvisibility=hidden \ -Wall -Wextra -Werror \ main.c -o prog
# Mostrare le directory di ricerca include gcc -v -E -x c /dev/null # Mostrare tutte le flag abilitate per un livello di ottimizzazione gcc -O2 -Q --help=optimizers # GCC clang -O2 -mllvm -print-all-options # Clang # CPU supportate gcc -march=native -Q --help=target clang -print-supported-cpus # AST dump (Clang) clang -Xclang -ast-dump -fsyntax-only main.c # Tempo di compilazione per fase gcc -ftime-report main.c -o prog clang -ftime-report main.c -o prog # GCC: dump delle rappresentazioni interne gcc -fdump-tree-all -O2 main.c # dump di tutti i pass GIMPLE
# CMake genera compile_commands.json cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -B build # Per progetti basati su make: usare Bear bear -- make # Usato automaticamente da clang-tidy, clangd (LSP), e altri tool