C/C++
C and C++ are low-level, high-performance languages used when you need tight control over memory, latency, and hardware. They power operating systems, databases, game engines, ML runtimes, and embedded firmware — anywhere raw performance and predictable resource use are non-negotiable.
That power demands discipline. Undefined behavior and unsafe memory use create subtle bugs and security vulnerabilities, which is why "modern C++" (C++17/20/23) emphasizes RAII, smart pointers, and the standard library to make safe code the default. If your main constraint is developer speed and you don't need native performance, a higher-level language is usually the better trade.
TL;DR
- Low-level, maximum-performance languages with manual control over memory.
- They reward discipline — undefined behavior and memory bugs are real risks.
- Modern C++: prefer RAII, smart pointers, and
std::vectorover raw pointers/arrays. - Use sanitizers (ASan/UBSan/TSan) in CI to catch memory and threading bugs.
Quick Example
RAII ties resource lifetime to scope — the file closes automatically when the stream goes out of scope:
C vs C++
- C — a small, simple core with manual memory management; great for ABI stability, embedded, and OS-level code.
- C++ — builds on C with stronger abstractions (RAII, templates, the STL), at the cost of considerable complexity.
Most modern codebases adopt "modern C++" practices to reduce foot-guns.
Core Concepts
Memory & ownership
Understand stack vs heap, lifetimes, and aliasing. In C++, prefer RAII and smart pointers over manual new/delete.
Undefined behavior (UB)
UB means the compiler may assume "this never happens," producing surprising results. Common sources: out-of-bounds access, use-after-free, uninitialized reads, and signed integer overflow. Avoiding UB is the core safety discipline.
The standard library (STL)
Containers (vector, string, unordered_map), algorithms (sort, transform), and utilities (optional, variant, span).
Concurrency
Threads, atomics, and memory ordering are powerful but easy to misuse. Prefer higher-level primitives (thread pools, message passing) and verify with ThreadSanitizer.
Tooling
- Build: CMake is the common default.
- Compilers: clang, gcc, MSVC.
- Debug/analyze: lldb/gdb, sanitizers (ASan, UBSan, TSan), profilers.
- Format/lint: clang-format, clang-tidy.
Best Practices (modern C++)
- Prefer value types and RAII; let destructors manage resources.
- Use
std::unique_ptrfor single ownership;std::shared_ptronly when sharing is truly required. - Prefer
std::vectorover raw arrays;std::stringover C strings. - Run sanitizers in CI (AddressSanitizer, UndefinedBehaviorSanitizer, ThreadSanitizer).
- Keep headers small to limit template/compile-time bloat.
Common Mistakes
Mixing ownership models
Iterator invalidation
Security
- Prefer bounds-checked access where feasible; avoid unsafe C string functions.
- Fuzz parsers and complex input handling.
- Follow safety guidelines where applicable (CERT C/C++, MISRA for embedded).
FAQ
When should I use C or C++?
When you need maximum performance and tight control over memory/hardware: operating systems, drivers, embedded firmware, databases, game engines, and performance-critical libraries. For typical application development where developer velocity matters more, a higher-level language is usually a better fit.
C or C++?
C for minimal, ABI-stable, embedded, or OS-level code where simplicity matters. C++ when you want abstractions (RAII, the STL, generics) to manage complexity at scale — most application-level native code uses modern C++.
What is undefined behavior and why is it dangerous?
UB is code the standard doesn't define the result of (out-of-bounds access, use-after-free, signed overflow). The compiler may optimize assuming it never occurs, producing crashes, security holes, or "impossible" behavior. Avoiding UB — with sanitizers and safe constructs — is central to writing correct C/C++.
Is C++ still relevant given Rust?
Yes. Rust offers compile-time memory safety and is excellent for new systems code, but C++ has vast existing codebases, mature tooling, and ecosystems (games, HPC, finance) that aren't going anywhere. Modern C++ also significantly improves safety. See Rust.
Related Topics
- Memory Management — Ownership, RAII, and smart pointers
- Rust — Compile-time memory safety alternative
- Systems Programming — The broader domain
- Concurrency Patterns — Threading done safely
- Programming Languages — The broader landscape