Skip to main content

Overview

Dolphin uses clang-format 19.1 to enforce consistent code formatting across the entire codebase. This guide details the specific coding standards and formatting rules.
In case of conflicts between this guide and clang-format rules, follow clang-format.

Setting Up clang-format

Automated Formatting

Format all staged files before committing:
git diff --cached --name-only | grep -E '[.](cpp|h|mm)$' | xargs -I {} clang-format -i {}

Line Endings

Windows users must configure git to checkout UNIX-style line endings:
git config core.autocrlf input

General Formatting Rules

Line Length and Indentation

  • Maximum line length: 100 characters
  • Indentation: 2 spaces per level (no tabs)
  • Tab width: 2 spaces
Try to keep lines under 80-90 characters when possible for better readability.

Brace Placement

Opening braces go on the next line for:
  • Namespaces
  • Classes
  • Functions
  • Enums, structs, unions
  • Conditionals and loops
// Correct
void MyFunction()
{
  if (condition)
  {
    DoSomething();
  }
}

// Exception: Array initializers and lambdas can keep braces on same line
auto lambda = [](int x) { return x * 2; };
int array[] = {1, 2, 3};

Pointers and References

Place the * or & against the type name, not the variable name:
// Correct
int* pointer;
int& reference;

// Incorrect
int *pointer;
int &reference;

Comments

Use single-line comments (//), not multi-line comments (/* */):
// This is correct
// Multiple lines use multiple single-line comments

/* This is incorrect */

Conditionals and Loops

Don’t collapse single-line bodies onto the same line as the header:
// Correct
if (condition)
  return 0;

while (var != 0)
  var--;

// Incorrect
if (condition) return 0;
while (var != 0) var--;

Naming Conventions

Classes, Enums, Functions, Structs

Use UpperCamelCase. Uppercase abbreviations:
class SomeClassName { };
enum IPCCommandType { };
void ProcessRequest();
struct GameMetadata { };

Constants

Fully uppercase with underscores:
constexpr double PI = 3.14159;
constexpr int MAX_PATH = 260;

Variables

Lowercase with underscores:
int this_variable_name;
float player_speed;

Variable Prefixes

Do not use Hungarian notation except for these specific prefixes:
PrefixUsageExample
g_Global variablesg_video_backend
m_Class member variablesm_width
s_Static variabless_instance_count
class ExampleClass
{
private:
  int m_x;                    // Member variable
  static int s_instance_count; // Static variable
};

int g_global_counter;          // Global variable

Conditional Statements

Don’t leave else or else if dangling unless the if lacks braces:
// Correct
if (condition)
{
  // code
}
else
{
  // code
}

// Also acceptable
if (condition)
  // single line
else
  // single line

// Incorrect - inconsistent bracing
if (condition)
{
  // code
}
else
  // single line

Classes and Structs

When to Use Each

Class Layout

Order sections as: public, protected, private Within each section, order as:
  1. Constructor
  2. Destructor
  3. Operator overloads
  4. Functions
  5. Variables (static before non-static)
class ExampleClass : public SomeParent
{
public:
  ExampleClass(int x, int y);
  ~ExampleClass();

  int GetX() const;
  int GetY() const;

protected:
  virtual void SomeProtectedFunction() = 0;
  static float s_some_variable;

private:
  int m_x;
  int m_y;
};

Final and Override Specifiers

Mark classes/functions that shouldn’t be inherited/overridden with final:
class ClassName final : ParentClass
{
public:
  void Update() final;  // Cannot be overridden
};
Mark overridden functions with override:
class ClassName : ParentClass
{
public:
  void Update() override;  // Overrides parent's Update()
};

Code-Specific Guidelines

Modern C++ Practices

1

Use nullptr

Use nullptr instead of the NULL macro:
int* ptr = nullptr;  // Correct
int* ptr = NULL;     // Incorrect
2

Prefer range-based for loops

Use range-based for loops over iterators when possible:
for (const auto& item : container)
{
  // process item
}
3

Avoid raw pointers

Prefer STL containers and smart pointers:
std::vector<int> data;           // Instead of int*
std::unique_ptr<Object> obj;     // For single ownership
Raw pointers are acceptable when interfacing with C libraries or when unavoidable.
4

Limit auto usage

Only use auto when the type is obvious:
// Good - type is clear
auto it = map.begin();
auto lambda = [](int x) { return x * 2; };

// Bad - type is not obvious
auto result = CalculateComplexValue();

Header Files

1

Use #pragma once

This project uses #pragma once as header guards.
2

Include order

Order includes in source files as:
  1. The header for this source file
  2. Standard library headers (alphabetically)
  3. System-specific headers (in #ifdef blocks)
  4. Other Dolphin headers (alphabetically)
#include "Core/MyClass.h"

#include <algorithm>
#include <vector>

#ifdef _WIN32
#include <windows.h>
#endif

#include "Common/CommonTypes.h"
#include "Core/ConfigManager.h"
3

Relative paths

Include project headers relative to [Dolphin Root]/Source/Core:
#include "VideoCommon/RenderBase.h"
4

Remove unused includes

Remove unnecessary or duplicate includes.

Loops

// Infinite loops
while (true)  // Correct
{
}

for (;;)      // Incorrect
{
}

// Empty loops
while (condition) {}  // Correct - use braces
while (condition);    // Incorrect - don't use semicolon

// Do-while loops
do
{
  // code
} while (false);      // 'while' on same line as closing brace

// Prefer prefix increment
for (int i = 0; i < n; ++i)  // Correct
for (int i = 0; i < n; i++)  // Less preferred

Functions

Const-correctness for parameters:
void ProcessData(const int* data, const size_t size);
Pointer parameters for modification: Make modification syntactically obvious by using pointers:
// Correct - obvious that val is modified
template<class T>
inline void Clamp(T* val, const T& min, const T& max)
{
  if (*val < min)
    *val = min;
  else if (*val > max)
    *val = max;
}

// Usage makes modification clear
Clamp(&var, 1000, 5000);

Miscellaneous

  • Avoid goto unless you have a really good reason
  • Fix compiler warnings when found
  • Don’t use using namespace [x]; in headers (avoid it elsewhere too)
  • Use prefix increment in for-loops: ++var instead of var++

clang-format Configuration

The project’s .clang-format file (located at Source/.clang-format) defines:
ColumnLimit: 100
IndentWidth: 2
PointerAlignment: Left
BreakBeforeBraces: Custom
BraceWrapping:
  AfterClass: true
  AfterControlStatement: true
  AfterEnum: true
  AfterFunction: true
  AfterNamespace: true
  AfterStruct: true
Standard: Latest
InsertNewlineAtEOF: true
View the complete configuration at Source/.clang-format in the repository.

Android Code Style

Kotlin

Use the built-in official Kotlin code style in Android Studio.

Java

Import the Dolphin Java code style:
1

Open Code Style settings

Navigate to Settings → Code Style in Android Studio.
2

Import scheme

Click the gear icon, select Import Scheme, and choose dolphin/Source/Android/code-style-java.xml.
3

Format code

Select code and press Ctrl+Alt+L to automatically format it.

Next Steps

Testing

Learn about testing practices and frameworks

Debugging

Explore debugging tools and techniques