C++

C++ Code Review with LGTM

AI code review for C++: LGTM catches undefined behavior risks, dangling references, missing RAII patterns, integer overflow, smart-pointer misuse, and concurrency hazards in modern (C++17/20/23) code.

How LGTM reviews C++ PRs

Tree-sitter's C++ grammar parses modern C++ (17/20/23) including templates, concepts, ranges, modules, coroutines, lambdas, and structured bindings. Older C++98/03 also parses cleanly.

Per-PR: PageRank ranks symbols related to the diff (classes, free functions, template specializations), context attached to agent prompts. The Bugs agent for C++ focuses on the undefined-behavior, memory-safety, and concurrency failure modes that C++'s power enables.

C++ is the language where the gap between 'compiles fine' and 'works correctly' is widest. LGTM's value is in flagging the patterns that compile fine but bite at runtime — buffer overruns, lifetime violations, signed-int overflow, etc.

Common C++ bugs LGTM catches

Dangling references / use-after-move. `auto& ref = vec[0]; vec.push_back(x); use(ref);` — push_back may reallocate, invalidating ref. The Bugs agent reads vector/string member calls following reference acquisition.

Missing RAII. `FILE* fp = fopen(...);` without a ScopeGuard or RAII wrapper. C++ has unique_ptr / file streams / scope_exit — recommend modern equivalent.

Signed integer overflow. `int a = INT_MAX; int b = a + 1;` — UB. The agent flags arithmetic on signed types where overflow is reasonably possible.

Smart pointer misuse. `shared_ptr` where `unique_ptr` would do (cost). `unique_ptr` passed by value when reference would be sufficient (copy of unique_ptr is illegal — caught at compile time, but the design smell is worth flagging earlier).

Concurrency hazards. `std::mutex` locked across blocking I/O. `std::atomic` used wrong (e.g., compound operations needing CAS). Static locals in multi-threaded init (post-C++11 standardized but easy to misuse).

Implicit narrowing conversions. `int x = 1000000000000;` — silently truncates. Modern compilers warn; the agent surfaces the design issue (use auto + appropriate literal suffix).

Tree-sitter coverage for C++

Modern C++ syntax is the hardest grammar to parse in tree-sitter's catalog. The C++ grammar is robust for 99% of real code but has edge cases (heavily-template-metaprogrammed Boost-style code) where ERROR nodes appear.

When tree-sitter produces ERROR nodes in a file, LGTM falls back to diff-only review for that file. Most files parse cleanly; the exceptions are usually meta-programming-heavy library code, not application logic.

Preprocessor directives are visible as tokens but not expanded. Macro-heavy code is reviewable as written; what the macro expands to isn't reasoned about.

Build systems: CMakeLists.txt is recognised for project layout. Bazel BUILD files supported via tree-sitter's separate grammar.

Setup notes for C++ projects

Install the LGTM GitHub App. Index time: 1-3 minutes for typical C++ projects, longer for templates-heavy code.

Header + source split: .h / .hpp / .cc / .cpp / .cxx all indexed. Header-only libraries reviewed too.

Generated code (protoc .pb.cc, Qt moc_*.cpp) auto-excluded by header heuristics.

Modern (C++17+) projects get fuller review because more idioms are recognised. Pre-C++11 projects work but the agents have less to suggest beyond classical patterns.

Example bugs LGTM catches

Reference invalidated by push_back
// ❌ Bug: ref into vector becomes dangling
std::vector<int> v = {1, 2, 3};
int& ref = v[0];
v.push_back(4);    // <-- may reallocate
std::cout << ref;  // <-- dangling read

// LGTM finding:
// "v.push_back(4) may invalidate references into v. 'ref'
//  was taken before push_back and is potentially dangling
//  after. Re-read via v[0] after the modification, or take
//  the value (int copy = v[0])."
Mutex held across blocking call
// ❌ Bug: blocks other threads on a network call
std::mutex m;
void update_user(int id) {
    std::lock_guard<std::mutex> lock(m);
    auto data = fetch_from_db(id);   // <-- blocks!
    cache_[id] = data;
}

// LGTM finding:
// "Mutex 'm' is held across fetch_from_db, which is a
//  blocking I/O call. Other threads needing 'm' wait for
//  the network. Restructure: fetch outside the lock, then
//  briefly lock for the cache write."

See LGTM reviewing C++

C++17/20/23 · RAII / UB / lifetime focus · CMake aware

Go to the product page

C++ review FAQs

C++ vs C — separate support?

Both parsed (separate tree-sitter grammars). C-only files (.c) get the C-focused agent heuristics. .cpp / .cc / .cxx get the C++ heuristics. Mixed projects work fine.

Template-heavy code support?

Parses but the agents reason about templates at the lexical level — what the template body says, what's instantiated. Concept-heavy meta-programming code may produce occasional 'I'm not sure what this means' findings.

CUDA / OpenCL kernels?

.cu / .cuh files parse with the CUDA tree-sitter grammar (an extension of C++). Kernel-specific patterns (warp divergence, memory coalescing) are NOT specifically recognised by the agents — general C++ review applies.

Game engine / embedded contexts?

Reviewed the same way as application C++. The agents don't have specific Unreal / Unity-native / FreeRTOS heuristics — but the general findings (RAII, lifetime, UB) apply.

Cost per C++ review?

$0.08-$0.20 for a 300-line PR on GPT-4o via BYOK. C++'s verbosity + the longer context typically attached (templates, headers) means higher token cost than Python/Go. Use Haiku/Mini variants for cheaper passes.

Related across LGTM

Other languages