← Kursa Dön
📄 Text · 15 min

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:

KategoriAçıklamaÖrnekler
Compile-timeDerleyicinin kendi uyarıları-Wall, -Wextra
External toolsAyrı araçlarla yapılan analizclang-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 main

Her flag'in ne yaptığını anlayalım:

FlagNe Yapar
-Wall"Tüm" yaygın uyarıları açar (aslında hepsini değil)
-WextraWall'ın kapsamadığı ek uyarıları açar
-WpedanticISO C++ standardına tam uyumu kontrol eder
-WerrorHer 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 --version

Temel 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-checks

Temel 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:

GrupAçıklama
errorKesin hatalar (varsayılan olarak açık)
warningOlası sorunlar
styleStil ve best practice kontrolleri
performancePerformans sorunları
portabilityTaşınabilirlik sorunları
informationBilgilendirme mesajları
allHepsini 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.

Özellikclang-tidycppcheck
AltyapıClang/LLVM AST tabanlıKendi token/AST parser'ı
Derleyici gereksinimiClang gerekliBağımsız
Otomatik düzeltmeEvet (-fix)Hayır
Modern C++ kontrolleriÇok güçlüSınırlı
Bellek analiziOrtaGüçlü
Konfigürasyon.clang-tidy YAMLKomut satırı / XML
HızYavaş (tam AST)Hızlı
False positiveAzOrta
Öğrenme eğrisiOrtaDüşü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.cpp

Formatlama Ö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-format eklentisi

  • Emacs: 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 -Werror

Bu 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 -Werror

  • clang-format kontrolü (sadece değişen dosyalarda)

Aşama 2 — Orta:

  • cppcheck --enable=warning,performance

  • clang-tidy: bugprone-*, performance-*

Aşama 3 — Gelişmiş:

  • clang-tidy: tüm kontroller (seçilenler hariç)

  • cppcheck --enable=all

  • Her 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?

SenaryoTavsiye
Açık kaynak projeSonarCloud (ücretsiz) + clang-tidy + cppcheck
Küçük-orta şirketSonarQube Community + clang-tidy
Büyük şirket / güvenlik kritikPVS-Studio veya SonarQube Enterprise
Otomotiv / havacılıkPVS-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.cpp

CMakeLists.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:

  1. Kod yaz → Editör clang-format ile otomatik formatlar

  2. Derle → Compiler uyarıları + clang-tidy + cppcheck çalışır

  3. Commit → Pre-commit hook formatı kontrol eder

  4. Push → CI pipeline tüm kontrolleri tekrar çalıştırır

  5. 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
fi

3. 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