C++ Code Review | 'Checklist' 20 Items [Production Essential]

C++ Code Review | 'Checklist' 20 Items [Production Essential]

이 글의 핵심

C++ Code Review - "Checklist" 20 Items [Production Essential]. Explains memory safety (5), performance (5), and readability (5) for C++ code review with practical code examples.

Memory Safety (5)

1. Check Memory Leaks

Below is an implementation example using C++. Understand the role of each part while examining the code.

// ❌ Leak
void bad() {
    int* ptr = new int[100];
    // No delete[]!
}

// ✅ RAII
void good() {
    vector<int> v(100);  // Automatic deallocation
}

2. Dangling Pointers

Below is an implementation example using C++. Understand the role of each part while examining the code.

// ❌ Dangerous
int* bad() {
    int x = 10;
    return &x;  // Returning local variable address!
}

// ✅ Safe
int good() {
    int x = 10;
    return x;  // Return value
}

3. double delete

Below is an implementation example using C++. Understand the role of each part while examining the code.

// ❌ Crash
int* ptr = new int(10);
delete ptr;
delete ptr;  // double delete!

// ✅ Set nullptr
int* ptr = new int(10);
delete ptr;
ptr = nullptr;
delete ptr;  // Safe

4. Array Out of Bounds

Below is an implementation example using C++. Perform branching with conditionals. Understand the role of each part while examining the code.

// ❌ Dangerous
int arr[10];
arr[10] = 5;  // Out of bounds!

// ✅ Check
if (index < 10) {
    arr[index] = 5;
}

// ✅ Use vector
vector<int> v(10);
v.at(10) = 5;  // Throws exception

5. Use Smart Pointers

Below is an implementation example using C++. Try running the code directly to check its operation.

// ❌ raw pointer
int* ptr = new int(10);
// ....complex logic ...
delete ptr;  // Easy to forget

// ✅ Smart pointer
auto ptr = make_unique<int>(10);
// Automatic deallocation

Understanding with everyday analogy: Think of memory as an apartment building. Stack is like an elevator - fast but limited space. Heap is like a warehouse - spacious but takes time to find things. Pointers are like notes pointing to addresses like “Floor 3, Room 302”.

Performance (5)

6. Unnecessary Copying

Below is an implementation example using C++. Try running the code directly to check its operation.

// ❌ Copy
void process(vector<int> data) {  // Copy!
    // ...
}

// ✅ Reference
void process(const vector<int>& data) {
    // ...
}

7. Use reserve

Below is an implementation example using C++. Process data with loops. Understand the role of each part while examining the code.

// ❌ Multiple reallocations
vector<int> v;
for (int i = 0; i < 1000; i++) {
    v.push_back(i);
}

// ✅ Pre-allocate
vector<int> v;
v.reserve(1000);
for (int i = 0; i < 1000; i++) {
    v.push_back(i);
}

8. Appropriate Data Structure

Below is an implementation example using C++. Understand the role of each part while examining the code.

// ❌ Slow (O(n) search)
vector<int> v;
find(v.begin(), v.end(), x);

// ✅ Fast (O(log n) or O(1))
set<int> s;
s.find(x);

unordered_set<int> us;
us.find(x);

9. String Concatenation

Below is an implementation example using C++. Process data with loops. Understand the role of each part while examining the code.

// ❌ Slow
string result;
for (const auto& s : strings) {
    result += s;  // Reallocation each time
}

// ✅ Fast
ostringstream oss;
for (const auto& s : strings) {
    oss << s;
}
string result = oss.str();

10. move Semantics

Below is an implementation example using C++. Try running the code directly to check its operation.

// ❌ Copy
vector<int> v1 = getData();
vector<int> v2 = v1;  // Copy

// ✅ move
vector<int> v1 = getData();
vector<int> v2 = move(v1);  // move

Readability (5)

11. Clear Variable Names

Below is an implementation example using C++. Try running the code directly to check its operation.

// ❌ Unclear
int d;  // What does it mean?
int tmp;

// ✅ Clear
int daysUntilExpiry;
int userCount;

12. Function Length

Here is detailed implementation code using C++. Understand the role of each part while examining the code.

// ❌ Too long function (100+ lines)
void processData() {
    // ....100 lines ...
}

// ✅ Split into small functions
void validateData() { /* ....*/ }
void transformData() { /* ....*/ }
void saveData() { /* ....*/ }

void processData() {
    validateData();
    transformData();
    saveData();
}

13. Remove Magic Numbers

Here is detailed implementation code using C++. Perform branching with conditionals. Understand the role of each part while examining the code.

// ❌ Magic number
if (status == 2) {  // What is 2?
    // ...
}

// ✅ Constant
const int STATUS_ACTIVE = 2;
if (status == STATUS_ACTIVE) {
    // ...
}

// ✅ enum
enum class Status { Inactive, Pending, Active };
if (status == Status::Active) {
    // ...
}

14. Comments

Below is an implementation example using C++. Try running the code directly to check its operation.

// ❌ Unnecessary comment
int x = 10;  // Assign 10 to x

// ❌ Outdated comment
// TODO: Fix later (2020)

// ✅ Explain intent
// Set timeout to 10 seconds (considering server response time)
int timeout = 10;

15. const Correctness

Below is an implementation example using C++. Process data with loops. Understand the role of each part while examining the code.

// ❌ No const
void print(vector<int>& v) {
    for (int x : v) {
        cout << x << " ";
    }
}

// ✅ Add const
void print(const vector<int>& v) {
    for (int x : v) {
        cout << x << " ";
    }
}

Safety (5)

16. Exception Safety

Below is an implementation example using C++. Understand the role of each part while examining the code.

// ❌ Leak on exception
void bad() {
    int* ptr = new int[100];
    riskyOperation();  // May throw exception
    delete[] ptr;  // Not executed!
}

// ✅ RAII
void good() {
    vector<int> v(100);
    riskyOperation();  // Safe even if exception thrown
}

17. nullptr Check

Below is an implementation example using C++. Ensure stability through error handling and perform branching with conditionals. Understand the role of each part while examining the code.

// ❌ No check
void process(int* ptr) {
    *ptr = 10;  // What if ptr is nullptr?
}

// ✅ Check
void process(int* ptr) {
    if (!ptr) {
        throw invalid_argument("ptr is null");
    }
    *ptr = 10;
}

18. Integer Overflow

Below is an implementation example using C++. Ensure stability through error handling, perform branching with conditionals, and try running the code directly to check its operation.

// ❌ Overflow possible
int a = INT_MAX;
int b = a + 1;  // Overflow!

// ✅ Check
if (a > INT_MAX - 1) {
    throw overflow_error("overflow");
}
int b = a + 1;

19. Input Validation

Below is an implementation example using C++. Ensure stability through error handling and perform branching with conditionals. Understand the role of each part while examining the code.

// ❌ No validation
void setAge(int age) {
    this->age = age;  // Negative possible?
}

// ✅ Validation
void setAge(int age) {
    if (age < 0 || age > 150) {
        throw invalid_argument("invalid age");
    }
    this->age = age;
}

20. Thread Safety

Here is detailed implementation code using C++. Understand the role of each part while examining the code.

// ❌ Race condition
int counter = 0;

void increment() {
    counter++;  // Not thread-safe!
}

// ✅ mutex
mutex mtx;
int counter = 0;

void increment() {
    lock_guard<mutex> lock(mtx);
    counter++;
}

Code Review Process

1. Automatic Checks

Below is an implementation example using bash. Ensure stability through error handling and try running the code directly to check its operation.

# Compilation warnings
g++ -Wall -Wextra -Werror

# Static analysis
cppcheck --enable=all .
clang-tidy *.cpp

# Format check
clang-format -i *.cpp

2. Manual Checks

Below is an implementation example using code. Try running the code directly to check its operation.

□ Does code meet requirements?
□ Are tests sufficient?
□ Is error handling appropriate?
□ Are there performance issues?
□ Are there security vulnerabilities?
□ Is readability good?
□ Is it documented?

3. Writing Feedback

Below is an implementation example using code. Try running the code directly to check its operation.

✅ Good feedback:
"line 42: Receiving vector as const reference can avoid copying."

❌ Bad feedback:
"This code is a mess."

Practical Examples

Example 1: Code Before Review

Below is an implementation example using C++. Process data with loops. Understand the role of each part while examining the code.

void process(vector<int> data) {
    int* arr = new int[data.size()];
    
    for (int i = 0; i <= data.size(); i++) {
        arr[i] = data[i] * 2;
    }
    
    // ....processing ...
    
    delete arr;  // Not delete[]!
}

Issues:

  1. Unnecessary copy (vector)
  2. Using raw pointer
  3. Out of bounds (i <= size)
  4. delete vs delete[]

Example 2: Code After Review

Below is an implementation example using C++. Process data with loops. Understand the role of each part while examining the code.

void process(const vector<int>& data) {
    vector<int> result;
    result.reserve(data.size());
    
    for (int value : data) {
        result.push_back(value * 2);
    }
    
    // ....processing ...
}

Improvements:

  1. Removed copy with const reference
  2. Using vector (RAII)
  3. Range-based for
  4. Performance improvement with reserve

FAQ

Q1: How often should code review be done?

A: Ideally review every PR/commit.

Q2: How many reviewers?

A: Minimum 1, recommend 2 or more for important code.

Q3: Review time?

A: About 1 hour per 200-400 lines is appropriate.

Q4: Automation tools?

A:

  • clang-tidy
  • cppcheck
  • SonarQube
  • Coverity

Q5: Code review culture?

A:

  • Constructive feedback
  • Suggest improvements, don’t attack code
  • Use as learning opportunity

Q6: How to create review checklist?

A:

  1. Analyze team’s past bugs
  2. Organize frequently occurring mistakes
  3. Include coding style guide

Other articles connected to this topic.

  • C++ const Complete Guide |
  • C++ Static Analysis Tools | Clang-Tidy·Cppcheck·SonarQube [#53-5]
  • Arrays and Lists | Essential Data Structures for Coding Tests Complete Summary
  • C++ Adapter Pattern Complete Guide | Interface Conversion and Compatibility
  • C++ ADL |