How I Review C++.

Introduction

I did not really learn C++ by writing it. I first learned it by reviewing it, looking at other people’s code and then by writing code myself.

At some point, reviews stopped being about style and started being about risk. In C++, risk hides in many different places. Most of the time the code can compile, pass tests, and still be wrong in a way that only shows up later on.

Here is what I typically look for when reviewing C++ code. The reason why I write it is because I see a lot of people nit-picking on useless things and style rather than solving a particular problem.

Correctness and Invariants First

Before performance, before elegance, I look for invariants.

What must be true before this function runs. What is guaranteed after. I scan for classic undefined behavior traps. Out-of-bounds access, dangling references, invalidated iterators, signed overflow, use-after-move, and lifetime issues with views like std::span or std::string_view.

If the invariants are not explicit, I push to make them explicit. Assertions are cheaper than outages.

Ownership and Lifetimes

In C++, types are documentation. Ownership should be obvious. std::unique_ptr for sole ownership. std::shared_ptr only when sharing is real. Raw pointers and references for non-owning relationships. Views are powerful, but only if the underlying storage outlives them. I typically think of “who owns what”.

RAII and Exception Safety

Manual resource management is a smell. Resources should be tied to objects. Construction acquires. Destruction releases. That is the RAII principle. I also check exception guarantees. At minimum, does the code provide the basic guarantee. No leaks. No half-updated objects. Destructors should not throw.

Interfaces That Resist Misuse

Good C++ APIs make the wrong thing hard. I prefer explicit interfaces and strong types over loosely defined integers and strings. If an API is easy to misuse, someone eventually will. Of course this depends on the context.

Consistency, Concurrency, and Performance

Error handling must be consistent. Exceptions, std::expected (super cool!), or error codes. Pick a strategy and apply it systematically.

With concurrency, I slow down. I look for shared mutable state, unclear lifetimes across threads, and inconsistent locking. Subtle races are worse than loud crashes.

Performance comes last. I focus on algorithmic complexity and obvious waste in hot paths. Not premature micro-optimizations. I care about them only later on, unless they are obvious.

What I learned from reviewing C++

Reviewing C++ made me more disciplined. I care less about cleverness and more about guarantees. What does this code promise. What does it assume. What happens when it fails.

Also and most importantly when reviewing, I try to test the application/feature myself and not just reviewing the code.




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • Back of the envelope math for Computers
  • Modern C++ guide
  • Monte Carlo techniques for stock price estimation