Static Analysis Araçları
Bir binanın duvarlarına baktığında çatlak olup olmadığını kontrol etmek için binayı yıkıp yeniden inşa etmene gerek yok. Deneyimli bir mühendis dışarıdan bakarak, ölçüm aletleri kullanarak sorunları tespit eder. Static analysis tam olarak bu — kodunu çalıştırmadan, derlemeden bile önce olası hataları, güvenlik açıklarını ve stil sorunlarını otomatik olarak bulan araçlardır.
Elle code review yapmak önemlidir ama insan gözü yorulur, gözden kaçırır. Statik analiz araçları ise yorulmadan, her commit'te, her build'de aynı titizlikle kodunu tarar. Bu derste compiler uyarılarından başlayarak clang-tidy, cppcheck, clang-format gibi temel araçları öğrenecek, bunları CI/CD pipeline'ına nasıl entegre edeceğini göreceksin.
Static Analysis Nedir?
Çalışma Prensibi
Static analysis, kaynak kodu çalıştırmadan analiz etme işlemidir. Kod dosyalarını okur, AST (Abstract Syntax Tree) oluşturur ve önceden tanımlanmış kurallara göre potansiyel sorunları raporlar.
İki ana kategori var:
| Kategori | Açıklama | Örnekler |
|---|---|---|
| Compile-time | Derleyicinin kendi uyarıları | -Wall, -Wextra |
| External tools | Ayrı araçlarla yapılan analiz | clang-tidy, cppcheck, PVS-Studio |
Dynamic analysis (Valgrind, AddressSanitizer) programı çalıştırarak hata arar. Static analysis ise tek satır bile çalıştırmadan hata bulur. İkisi birbirini tamamlar — birinin bulduğunu diğeri kaçırabilir.
Ne Tür Hatalar Bulunur?
Static analysis araçları şu tür sorunları yakalar:
Bellek hataları: Null pointer dereference, buffer overflow, use-after-free
Kaynak sızıntıları: Kapatılmayan dosya, serbest bırakılmayan bellek
Tanımsız davranış: Signed integer overflow, uninitialized variable kullanımı
Mantık hataları: Dead code, unreachable branch, her zaman true olan koşul
Stil sorunları: Naming convention ihlali, gereksiz copy, modern C++ kullanılmayan yerler
Güvenlik açıkları: Format string vulnerability, tainted input kullanımı
Compiler Uyarıları: İlk Savunma Hattı
Temel Uyarı Flagları
Derleyici uyarıları en basit ve en etkili static analysis aracıdır. Çoğu proje varsayılan uyarı seviyesinde derlenir — bu da birçok hatanın gözden kaçması demektir.
# Temel uyarılar
g++ -Wall main.cpp -o main
# Daha kapsamlı uyarılar
g++ -Wall -Wextra main.cpp -o main
# En katı seviye
g++ -Wall -Wextra -Wpedantic main.cpp -o main
# Uyarıları hata olarak ele al (uyarı varsa derleme başarısız)
g++ -Wall -Wextra -Wpedantic -Werror main.cpp -o mainHer flag'in ne yaptığını anlayalım:
| Flag | Ne Yapar |
|---|---|
-Wall | "Tüm" yaygın uyarıları açar (aslında hepsini değil) |
-Wextra | Wall'ın kapsamadığı ek uyarıları açar |
-Wpedantic | ISO C++ standardına tam uyumu kontrol eder |
-Werror | Her uyarıyı derleme hatası yapar — uyarı varsa binary oluşmaz |
-Wall adına rağmen "tüm" uyarıları açmaz. Çoğu projede -Wall -Wextra yeterlidir. -Wpedantic özellikle taşınabilir kod yazarken faydalıdır.
Uyarıların Fark Yarattığı Örnek
Şu koda bakalım — uyarı olmadan derlenirse sorun belli olmaz:
#include <iostream>
#include <vector>
int topla(int a, int b) {
int sonuc = a + b;
// return sonuc; ← unuttuk!
}
void pisinlikliKod() {
int x; // Başlatılmadı
if (x > 0) { // UB: uninitialized read
std::cout << "Pozitif" << std::endl;
}
int sayilar[] = {1, 2, 3};
for (unsigned i = 0; i < 3; ++i) {
// signed/unsigned karşılaştırma uyarısı yok
// ama mantıksal hata gizlenebilir
}
}
int main() {
int sonuc = topla(3, 5);
std::cout << sonuc << std::endl; // Tanımsız davranış!
return 0;
}Uyarılar açıkken derleyici seni uyarır:
main.cpp:6:1: warning: non-void function does not return a value [-Wreturn-type]
main.cpp:10:9: warning: variable 'x' is uninitialized [-Wuninitialized]-Werror aktifken bu uyarılar derleme hatasına dönüşür ve hatalı binary asla oluşmaz.
CMake'de Uyarı Ayarları
Modern bir CMake projesinde uyarıları şöyle yapılandırırsın:
cmake_minimum_required(VERSION 3.14)
project(StaticAnalysisDemo)
set(CMAKE_CXX_STANDARD 17)
add_executable(main src/main.cpp)
# Compiler'a göre uyarıları ayarla
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
target_compile_options(main PRIVATE
-Wall -Wextra -Wpedantic -Werror
-Wshadow # Değişken gölgeleme uyarısı
-Wnon-virtual-dtor # Sanal olmayan destructor uyarısı
-Wold-style-cast # C-style cast uyarısı
-Wcast-align # Hizalama sorunlu cast uyarısı
-Woverloaded-virtual # Saklanan sanal fonksiyon uyarısı
)
elseif(MSVC)
target_compile_options(main PRIVATE
/W4 # Yüksek uyarı seviyesi
/WX # Uyarıları hata yap (-Werror karşılığı)
/permissive- # Katı standart uyumu
)
endif()⚠️ Dikkat: -Werror yeni başlayan projelerde harikadır ama büyük legacy projelerde binlerce uyarıyı bir anda hata yapmak projeyi derlenemez hale getirir. Bu tür projelerde uyarıları kademeli olarak temizle: önce yeni kodda -Werror zorla, eski kodu aşama aşama düzelt.
clang-tidy: C++ Linter ve Modernizer
Ne İşe Yarar?
clang-tidy, Clang/LLVM projesinin parçası olan güçlü bir static analysis aracıdır. Derleyici uyarılarının ötesine geçerek yüzlerce farklı kontrolü tek araçta sunar. Sadece hata bulmaz, aynı zamanda kodu otomatik olarak düzeltebilir.
Kurulum:
# Ubuntu/Debian
sudo apt install clang-tidy
# macOS
brew install llvm
# veya Xcode Command Line Tools ile gelir
# Versiyon kontrolü
clang-tidy --versionTemel Kullanım
En basit kullanım:
# Tek dosyayı analiz et
clang-tidy main.cpp -- -std=c++17
# Belirli kontrolleri çalıştır
clang-tidy -checks='modernize-*,bugprone-*' main.cpp -- -std=c++17
# Düzeltmeleri otomatik uygula
clang-tidy -checks='modernize-use-nullptr' -fix main.cpp -- -std=c++17-- sonrasındaki kısım derleyiciye geçecek argümanlardır. Eğer projen CMake kullanıyorsa compile_commands.json dosyası işini çok kolaylaştırır:
# CMake ile compile_commands.json oluştur
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -B build
# Artık include yollarını elle belirtmen gerekmez
clang-tidy -p build src/main.cpp.clang-tidy Konfigürasyon Dosyası
Proje kök dizininde .clang-tidy dosyası oluşturarak kalıcı konfigürasyon tanımlarsın:
---
Checks: >
-*,
bugprone-*,
modernize-*,
performance-*,
readability-*,
cppcoreguidelines-*,
-modernize-use-trailing-return-type,
-readability-magic-numbers,
-cppcoreguidelines-avoid-magic-numbers
WarningsAsErrors: >
bugprone-*,
performance-move-const-arg
HeaderFilterRegex: '.*'
CheckOptions:
- key: readability-identifier-naming.ClassCase
value: CamelCase
- key: readability-identifier-naming.FunctionCase
value: camelBack
- key: readability-identifier-naming.VariableCase
value: lower_case
- key: readability-identifier-naming.ConstantCase
value: UPPER_CASE
- key: modernize-use-override.IgnoreDestructors
value: true
- key: performance-unnecessary-value-param.AllowedTypes
value: 'shared_ptr;unique_ptr'
...İlk satırdaki -* tüm kontrolleri kapatır. Sonra istediğin kategorileri açarsın. Eksi ile başlayan isimler (-modernize-use-trailing-return-type) o spesifik kontrolü tekrar kapatır.
Yaygın ve Değerli Check'ler
bugprone kategorisi — potansiyel hatalar:
#include <string>
#include <iostream>
// bugprone-string-constructor: yanlış string oluşturma
void stringHatalari() {
// Kotu: 'A' harfinden 0 adet oluşturur (muhtemelen 65 istenmiş)
std::string s1('A', 0); // uyarı verir
// Iyi: doğru parametre sırası
std::string s2(5, 'A'); // "AAAAA"
}
// bugprone-use-after-move: move sonrası kullanım
void moveHatasi() {
std::string isim = "Merhaba";
std::string yeni = std::move(isim);
// Kotu: isim artık geçersiz durumda
std::cout << isim.size() << std::endl; // uyarı verir
}modernize kategorisi — modern C++ önerileri:
#include <memory>
#include <vector>
#include <iostream>
// modernize-use-nullptr: NULL yerine nullptr
void nullptrKullan() {
int* ptr = NULL; // uyarı: nullptr kullan
int* ptr2 = nullptr; // doğru
}
// modernize-use-auto: açık tip yazımını auto ile değiştir
void autoKullan() {
std::vector<int> v = {1, 2, 3};
// Uyarı: auto kullan
std::vector<int>::iterator it = v.begin();
// Doğru
auto it2 = v.begin();
}
// modernize-make-unique: new yerine make_unique
void makeUniqueKullan() {
// Uyarı: std::make_unique kullan
std::unique_ptr<int> p1(new int(42));
// Doğru
auto p2 = std::make_unique<int>(42);
}
// modernize-use-override: override keyword'ünü ekle
class Taban {
public:
virtual void calis() {}
virtual ~Taban() = default;
};
class Turetilmis : public Taban {
public:
void calis() {} // uyarı: override ekle
void calis2() override {} // (taban'da yok — derleme hatası verir, güzel)
};performance kategorisi — performans sorunları:
#include <string>
#include <vector>
// performance-unnecessary-copy-initialization
void gereksizKopyalar(const std::vector<std::string>& veriler) {
// Kotu: gereksiz kopya (const reference yeterli)
std::string ilk = veriler[0]; // uyarı
// Iyi: referans kullan
const std::string& ilk_ref = veriler[0];
}
// performance-for-range-copy
void donguKopya(const std::vector<std::string>& isimler) {
// Kotu: her iterasyonda kopya
for (std::string isim : isimler) { // uyarı
// ...
}
// Iyi: const reference
for (const std::string& isim : isimler) {
// ...
}
}
// performance-move-const-arg: const argümanı move etme
void constMove() {
const std::string s = "merhaba";
// Kotu: const'ı move edemezsin, kopya olur
std::string s2 = std::move(s); // uyarı
}CMake Entegrasyonu
CMake'in yerleşik clang-tidy desteği var:
# Yöntem 1: CMAKE_CXX_CLANG_TIDY değişkeni
set(CMAKE_CXX_CLANG_TIDY
clang-tidy
-p ${CMAKE_BINARY_DIR}
)
# Yöntem 2: target bazında
add_executable(main src/main.cpp)
set_target_properties(main PROPERTIES
CXX_CLANG_TIDY "clang-tidy;-p;${CMAKE_BINARY_DIR}"
)Bu ayarla her derleme sırasında clang-tidy otomatik çalışır. Build süresi uzar ama her hata anında yakalanır.
cppcheck: Bağımsız Static Analyzer
Ne İşe Yarar?
cppcheck, Clang ekosisteminden bağımsız bir static analysis aracıdır. Derleyiciye ihtiyaç duymaz. Özellikle bellek yönetimi hataları, tanımsız davranış ve stil sorunları konusunda güçlüdür.
Kurulum:
# Ubuntu/Debian
sudo apt install cppcheck
# macOS
brew install cppcheck
# Versiyon ve desteklenen kontroller
cppcheck --version
cppcheck --list-checksTemel Kullanım
# Tek dosya analizi
cppcheck main.cpp
# Tüm proje dizini
cppcheck src/
# Hata seviyesiyle filtrele
cppcheck --enable=all src/
# Inline suppressions aktif
cppcheck --inline-suppr src/
# XML çıktı (CI araçları için)
cppcheck --xml --xml-version=2 src/ 2> report.xml--enable parametresiyle hangi kontrol gruplarını aktif edeceğini belirlersin:
| Grup | Açıklama |
|---|---|
error | Kesin hatalar (varsayılan olarak açık) |
warning | Olası sorunlar |
style | Stil ve best practice kontrolleri |
performance | Performans sorunları |
portability | Taşınabilirlik sorunları |
information | Bilgilendirme mesajları |
all | Hepsini aç |
Bulduğu Hata Örnekleri
#include <cstring>
#include <cstdlib>
#include <iostream>
void cppcheckBulur() {
// Bellek sızıntısı
int* p = new int[10];
// delete[] p; ← unutulmuş
// cppcheck: memory leak: p
// Buffer overflow
char buf[10];
std::strcpy(buf, "Bu metin 10 karakterden uzun");
// cppcheck: Buffer is accessed out of bounds
// Null pointer dereference
int* ptr = nullptr;
*ptr = 42;
// cppcheck: Null pointer dereference
// Kullanılmayan değişken
int kullanilmayan = 99;
// cppcheck: Variable 'kullanilmayan' is not used
// Aynı koşulun tekrar kontrolü
int x = 5;
if (x > 0) {
if (x > 0) { // Aynı koşul tekrar
std::cout << x << std::endl;
}
}
// cppcheck: Duplicate condition
}Suppressions (Uyarı Bastırma)
Bazen belirli uyarıları kasıtlı olarak susturmak istersin. Üç yöntem var:
Inline suppression:
void bilincliFonksiyon() {
// cppcheck-suppress memleak
int* p = new int[10]; // Kasıtlı: başka yerde temizleniyor
}Suppression dosyası:
// suppressions.txt
memleak:src/legacy_code.cpp
uninitvar:src/third_party/*
style:tests/*cppcheck --suppressions-list=suppressions.txt src/CMake ile cppcheck:
find_program(CPPCHECK cppcheck)
if(CPPCHECK)
set(CMAKE_CXX_CPPCHECK
${CPPCHECK}
--enable=warning,performance
--suppress=missingIncludeSystem
--inline-suppr
)
endif()clang-tidy vs cppcheck Karşılaştırma
İki araç birbirini tamamlar. Her biri diğerinin yakalamadığı bazı sorunları bulur.
| Özellik | clang-tidy | cppcheck |
|---|---|---|
| Altyapı | Clang/LLVM AST tabanlı | Kendi token/AST parser'ı |
| Derleyici gereksinimi | Clang gerekli | Bağımsız |
| Otomatik düzeltme | Evet (-fix) | Hayır |
| Modern C++ kontrolleri | Çok güçlü | Sınırlı |
| Bellek analizi | Orta | Güçlü |
| Konfigürasyon | .clang-tidy YAML | Komut satırı / XML |
| Hız | Yavaş (tam AST) | Hızlı |
| False positive | Az | Orta |
| Öğrenme eğrisi | Orta | Düşük |
Tavsiye: İkisini birlikte kullan. clang-tidy modernize ve stil kontrolleri için, cppcheck bellek ve güvenlik kontrolleri için güçlüdür. CI pipeline'ında ikisi de çalışmalı.
clang-format: Otomatik Kod Formatlama
Neden Format Önemli?
Bir ekipte herkes farklı boşluk, satır sonu, parantez stili kullanırsa code review'lar format tartışmalarıyla harcanır. clang-format bu sorunu otomatik olarak çözer — kaydet ve unuttur.
Kurulum:
sudo apt install clang-format # Linux
brew install clang-format # macOS.clang-format Dosyası
Proje kök dizinine .clang-format dosyası koyarsın:
---
Language: Cpp
BasedOnStyle: Google
IndentWidth: 4
ColumnLimit: 100
BreakBeforeBraces: Attach
AllowShortFunctionsOnASingleLine: Inline
SortIncludes: CaseSensitive
PointerAlignment: Left
SpaceAfterCStyleCast: false
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<.*>'
Priority: 1
- Regex: '^".*"'
Priority: 2
...Kullanım:
# Tek dosya — formatlı çıktıyı terminalde göster
clang-format main.cpp
# Dosyayı yerinde değiştir
clang-format -i main.cpp
# Tüm src/ altındaki dosyaları formatla
find src/ -name '*.cpp' -o -name '*.h' | xargs clang-format -i
# Sadece farkı göster (kontrol amaçlı)
clang-format --dry-run -Werror main.cppFormatlama Öncesi ve Sonrası
Formatsız:
#include<iostream>
#include "utils.h"
#include<vector>
class Ogrenci{
public:
std::string isim;int yas;
Ogrenci(std::string i,int y):isim(i),yas(y){}
void yazdir(){std::cout<<isim<<" "<<yas<<std::endl;}
};
int main(){
auto o=Ogrenci("Ali",20);
o.yazdir();
return 0;
}clang-format sonrası (Google stiline yakın):
#include <iostream>
#include <vector>
#include "utils.h"
class Ogrenci {
public:
std::string isim;
int yas;
Ogrenci(std::string i, int y) : isim(i), yas(y) {}
void yazdir() {
std::cout << isim << " " << yas << std::endl;
}
};
int main() {
auto o = Ogrenci("Ali", 20);
o.yazdir();
return 0;
}Fark açık. Formatlama araçları ekip genelinde tutarlılık sağlar ve code review'ların içerikle ilgili tartışmalara odaklanmasını mümkün kılar.
Editor Entegrasyonu
Çoğu modern editör clang-format'ı destekler:
VS Code: "C/C++" veya "Clang-Format" eklentisi → kaydettiğinde formatla
CLion: Yerleşik destek → Settings > Editor > Code Style
Vim:
vim-clang-formateklentisiEmacs:
clang-format.el
Kaydet-formatla (format-on-save) aktif edildiğinde kod her zaman temiz kalır.
CI/CD Entegrasyonu
GitHub Actions Örneği
Gerçek bir CI pipeline'ında üç aracı birlikte çalıştıralım:
# .github/workflows/static-analysis.yml
name: Static Analysis
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
clang-tidy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install tools
run: |
sudo apt-get update
sudo apt-get install -y clang-tidy-17 cppcheck clang-format-17
- name: Configure CMake
run: cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
- name: Run clang-tidy
run: |
find src/ -name '*.cpp' | xargs clang-tidy-17 \
-p build \
--warnings-as-errors='*'
- name: Run cppcheck
run: |
cppcheck --enable=warning,performance,portability \
--error-exitcode=1 \
--suppress=missingIncludeSystem \
src/
- name: Check formatting
run: |
find src/ include/ -name '*.cpp' -o -name '*.h' | \
xargs clang-format-17 --dry-run -WerrorBu workflow her pull request'te çalışır. Üç kontrolden biri bile başarısız olursa PR merge edilemez.
Pipeline Stratejisi
Büyük projelerde tüm kontrolleri aynı anda açmak caydırıcıdır. Kademeli bir yaklaşım:
Aşama 1 — Temel:
Compiler uyarıları:
-Wall -Wextra -Werrorclang-format kontrolü (sadece değişen dosyalarda)
Aşama 2 — Orta:
cppcheck
--enable=warning,performanceclang-tidy:
bugprone-*,performance-*
Aşama 3 — Gelişmiş:
clang-tidy: tüm kontroller (seçilenler hariç)
cppcheck
--enable=allHer yeni dosyada hatasız politikası
💡 İpucu: "Ratchet" yaklaşımını kullan — mevcut uyarı sayısını kaydet, her commit'te bu sayının artmamasını zorunlu kıl. Zamanla uyarılar sıfıra iner, ama ekip asla "500 uyarıyı bir gecede düzelt" baskısı yaşamaz.
Ticari Static Analysis Araçları
SonarQube / SonarCloud
SonarQube açık kaynak (Community Edition) ve ticari (Developer/Enterprise) sürümleri olan kapsamlı bir kod kalite platformudur. C++ desteği ticari sürümlerde gelir.
Öne çıkan özellikleri:
Quality Gate: Belirlenen kalite eşiğini geçmeyen kod merge edilemez
Technical Debt: Kod borcu süresini dakika olarak hesaplar
Security Hotspot: Güvenlik açığı olabilecek yerleri işaretler
Trend grafikleri: Zaman içinde kalite değişimini gösterir
CI entegrasyonu bir sonar-project.properties dosyasıyla yapılır ve genellikle mevcut pipeline'a birkaç satır ekleme yeterlidir.
PVS-Studio
PVS-Studio, C, C++, C# ve Java için özelleştirilmiş ticari bir static analyzer'dır. Özellikle C++ konusundaki derin analizi ile bilinir.
Güçlü yönleri:
Derin interprocedural analysis: Fonksiyonlar arası veri akışını takip eder
Copy-paste hataları: Kopyala-yapıştır kaynaklı hataları bulur
64-bit taşıma sorunları: 32-bit'ten 64-bit'e geçiş hatalarını tespit eder
MISRA, AUTOSAR: Endüstriyel standart uyumluluk kontrolleri
Açık kaynak projeler ve öğrenciler için ücretsiz lisans sunar. Kodu satır satır tarayan blog yazıları (pvs-studio.com/blog) C++ öğrenenler için harika kaynaklardır.
Hangi Ticari Araç Ne Zaman?
| Senaryo | Tavsiye |
|---|---|
| Açık kaynak proje | SonarCloud (ücretsiz) + clang-tidy + cppcheck |
| Küçük-orta şirket | SonarQube Community + clang-tidy |
| Büyük şirket / güvenlik kritik | PVS-Studio veya SonarQube Enterprise |
| Otomotiv / havacılık | PVS-Studio (MISRA/AUTOSAR desteği) |
Araçları Birlikte Kullanmak: Pratik Proje
Proje Yapısı
Tüm araçları bir arada kullanan örnek bir proje yapısı:
my-project/
├── CMakeLists.txt
├── .clang-tidy
├── .clang-format
├── .github/
│ └── workflows/
│ └── ci.yml
├── include/
│ └── calculator.h
├── src/
│ └── calculator.cpp
└── tests/
└── calculator_test.cppCMakeLists.txt
cmake_minimum_required(VERSION 3.14)
project(Calculator LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Uyarılar
add_compile_options(
-Wall -Wextra -Wpedantic -Werror
-Wshadow -Wnon-virtual-dtor
)
# clang-tidy (varsa aktif et)
find_program(CLANG_TIDY clang-tidy)
if(CLANG_TIDY)
set(CMAKE_CXX_CLANG_TIDY ${CLANG_TIDY} -p ${CMAKE_BINARY_DIR})
endif()
# cppcheck (varsa aktif et)
find_program(CPPCHECK cppcheck)
if(CPPCHECK)
set(CMAKE_CXX_CPPCHECK
${CPPCHECK}
--enable=warning,performance
--suppress=missingIncludeSystem
--inline-suppr
)
endif()
# Kütüphane
add_library(calculator src/calculator.cpp)
target_include_directories(calculator PUBLIC include/)
# Ana program
add_executable(main src/main.cpp)
target_link_libraries(main calculator)Bu yapıda her cmake --build . çalıştığında hem compiler uyarıları hem clang-tidy hem cppcheck otomatik çalışır. Hatalı kod derleme aşamasını geçemez.
Geliştirme Akışı
Günlük geliştirme döngüsü şöyle görünür:
Kod yaz → Editör clang-format ile otomatik formatlar
Derle → Compiler uyarıları + clang-tidy + cppcheck çalışır
Commit → Pre-commit hook formatı kontrol eder
Push → CI pipeline tüm kontrolleri tekrar çalıştırır
PR Review → Sadece mantık ve tasarım tartışılır (format temiz, hatalar yakalanmış)
Bu döngü başlangıçta ek iş gibi görünür ama orta-uzun vadede ekip verimliliğini ve kod kalitesini dramatik şekilde artırır.
Best Practices
1. Küçük Başla, Büyüt
Mevcut bir projeye araç eklerken tüm kontrolleri birden açma. Önce compiler uyarılarını temizle. Sonra clang-format'ı zorunlu kıl. Sonra clang-tidy'ı kademeli olarak aç. Her adımda ekibin adapte olmasını bekle.
2. Pre-commit Hook Kullan
#!/bin/bash
# .git/hooks/pre-commit
# Formatı kontrol et
CHANGED=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(cpp|h|hpp)$')
if [ -n "$CHANGED" ]; then
echo "$CHANGED" | xargs clang-format --dry-run -Werror
if [ $? -ne 0 ]; then
echo "Format hatasi! 'clang-format -i' ile duzelt."
exit 1
fi
fi3. compile_commands.json Oluştur
clang-tidy'ın doğru çalışması için compile_commands.json gereklidir. CMake'de şu satır yeterlidir:
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)4. Suppression'ları Belgele
Bir uyarıyı bastırdığında neden bastırdığını yorum olarak ekle:
// Third-party kütüphane API'si gerektiriyor, değiştiremiyoruz
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto result = reinterpret_cast<char*>(buffer);5. Metrikleri Takip Et
Zamanla uyarı sayısının nasıl değiştiğini izle. SonarQube bunu otomatik yapar. Basit projelerde CI script'i ile bir dosyaya yazıp commit'leyebilirsin.
⚠️ Dikkat: Static analysis araçları false positive (yanlış alarm) üretebilir. Her uyarıyı kör bir şekilde düzeltme — uyarıyı anla, gerçek bir sorun mu yoksa araç hatası mı karar ver. Gerçek sorunsa düzelt, false positive ise bastır ve belgele.
Özet
Compiler uyarıları (
-Wall -Wextra -Werror) ilk savunma hattıdır — her projede açık olmalıclang-tidy modern C++ kontrolleri, otomatik düzeltme ve stil denetimi için en güçlü araçtır
cppcheck bellek analizi ve güvenlik kontrolleri konusunda clang-tidy'ı tamamlar — ikisini birlikte kullan
clang-format ile kod formatını otomatikleştir, ekip içi format tartışmalarını sıfırla
CI/CD pipeline'ında static analysis zorunlu olmalı — hatalı kod merge edilememeli
Araçları kademeli olarak ekle, ekibin adapte olmasını bekle ve false positive'leri dikkatle yönet
AI Asistan
Sorularını yanıtlamaya hazır