Skill: ivangdavila/cpp (version 1.0.1)

--- name: C++ slug: cpp version: 1.0.1 description: Write safe C++ avoiding memory leaks, dangling pointers, undefined behavior, and ownership confusion. metadata: {"clawdbot":{"emoji":"⚡","requires":{"bins":["g++"]},"os":["linux","darwin","win32"]}} --- ## Quick Reference | Topic | File | |-------|------| | RAII, smart pointers, new/delete | `memory.md` | | Raw pointers, references, nullptr | `pointers.md` | | Rule of 3/5/0, inheritance, virtual | `classes.md` | | Containers, iterators, algorithms | `stl.md` | | Templates, SFINAE, concepts | `templates.md` | | Threads, mutex, atomics | `concurrency.md` | | C++11/14/17/20, move semantics | `modern.md` | | Undefined behavior traps | `ub.md` | ## Critical Rules - Raw `new` without `delete` leaks — use `std::unique_ptr` or `std::make_unique` - Returning reference to local — undefined behavior, object destroyed on return - `==` for C-strings compares pointers — use `std::string` or `strcmp()` - Signed integer overflow is UB — not wrap-around like unsigned - Virtual destructor required in base class — otherwise derived destructor skipped - `std::move` doesn't move — it casts to rvalue, enabling move semantics - Moved-from object valid but unspecified — don't use without reassigning - Data race on non-atomic is UB — use `std::mutex` or `std::atomic` - `vector<bool>` is not a real container — returns proxy, use `deque<bool>` - `map[key]` inserts default if missing — use `find()` or `contains()` to check - Braced init `{}` prevents narrowing — `int x{3.5}` errors, `int x(3.5)` truncates - Iterator invalidation on `push_back` — vector may relocate, invalidating iterators - `string_view` doesn't own data — underlying string must outlive the view

path: classes.md
content: # Class Traps

- Rule of 3/5/0 — if custom destructor, need copy/move ctor and assignment
- Slicing — passing derived as base value copies only base part
- Virtual destructor — missing in base = UB when deleting derived via base ptr
- Pure virtual in destructor — can still define it, called during destruction
- Initialization order — members init in declaration order, not initializer list
- Most vexing parse — `A a()` declares function, not object; use `A a{}` 
- `explicit` constructor — prevents `A a = 5` implicit conversion
- `override` keyword — catches typos in virtual function signatures


path: concurrency.md
content: # Concurrency Traps

- Data race — concurrent read+write without sync is UB
- `mutex` not RAII — use `lock_guard` or `unique_lock`
- Deadlock — lock order must be consistent, use `scoped_lock`
- `volatile` is not atomic — doesn't prevent races, use `std::atomic`
- False sharing — adjacent atomics on same cache line = slow
- `condition_variable` spurious wake — always use predicate in `wait`
- `thread` must join/detach — destructor calls `terminate` otherwise
- `async` may be deferred — `std::launch::async` to force thread


path: memory.md
content: # Memory Traps

- `new` without `delete` — leak, use smart pointers instead
- `delete` vs `delete[]` — wrong one is UB, `delete[]` for arrays
- Double delete — UB, set pointer to nullptr after delete
- Returning local address — `return &localVar` is dangling pointer
- `unique_ptr` in container — use `std::move()` to insert
- `shared_ptr` cycles — use `weak_ptr` to break circular references
- `make_shared` exception safety — single allocation, prefer over `new`
- Stack overflow — large arrays/recursion, use heap or increase stack


path: modern.md
content: # Modern C++ Traps

- Move leaves valid state — but unspecified, don't use after move
- `auto` deduces value — `auto x = ref` copies, use `auto&` for reference
- Initializer list — `{}` prefers initializer_list ctor over others
- Lambda capture — `[=]` copies, `[&]` refs, `[this]` captures this
- `std::move` doesn't move — just casts to rvalue, move ctor does work
- Forwarding reference — `T&&` with deduction is universal, not rvalue
- `constexpr` if — evaluated at compile time, enables template branches
- Structured bindings — `auto [a, b] = pair;` copies unless `auto& [a,b]`


path: pointers.md
content: # Pointer Traps

- Null dereference — UB, check before access
- Dangling pointer — points to freed memory, UB on access
- Wild pointer — uninitialized, random memory location
- Array decay — `int arr[10]` becomes `int*` when passed, loses size
- `void*` arithmetic — can't do math on void*, cast first
- Reference to temp — `const int& r = getVal()` extends lifetime, non-const doesn't
- Pointer aliasing — optimizer assumes pointers don't overlap unless `restrict`
- `reinterpret_cast` — no conversion, just reinterprets bits, usually wrong


path: stl.md
content: # STL Traps

- Iterator invalidation — `vector` realloc invalidates ALL iterators
- `erase` in loop — returns next iterator, use `it = v.erase(it)`
- `map[]` creates entry — use `find()` or `contains()` to check existence
- `string::c_str()` — pointer invalid after string modified
- `vector<bool>` — not real bools, proxy objects, weird behavior
- `reserve` vs `resize` — `reserve` doesn't change size, `resize` does
- `emplace` vs `push` — `emplace` constructs in place, avoids copy
- Range `erase` — `v.erase(remove(...), v.end())` for remove-erase idiom


path: templates.md
content: # Template Traps

- Two-phase lookup — dependent names need `typename`/`this->` 
- Template in header — definition must be visible, not in .cpp
- SFINAE failure — substitution failure is not error, but confusing messages
- Argument deduction — `template<class T> void f(T)` deduces from args
- `>>` in nested templates — before C++11 needed space `> >`
- Static members — each instantiation has own static, not shared
- Explicit instantiation — `template class MyClass<int>;` forces compile
- Concepts (C++20) — `requires` constraints, better than SFINAE


path: ub.md
content: # Undefined Behavior Traps

- Signed overflow — `INT_MAX + 1` is UB, use unsigned or check
- Shift too far — `1 << 32` on 32-bit is UB
- Null dereference — UB, not just crash
- Uninitialized read — UB, variable has indeterminate value
- Out of bounds — array access beyond size is UB
- Strict aliasing — casting pointer types breaks optimizer assumptions
- Sequence points — `i++ + i++` is UB, order undefined
- ODR violation — same name, different definition across TUs


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)