Bjarne Stroustrup Style Guide
Overview
Bjarne Stroustrup created C++ in 1979 at Bell Labs, evolving it from "C with Classes" into the multi-paradigm language used in systems from browsers to databases to operating systems. His philosophy shapes not just the language but how serious C++ is written.
Core Philosophy
"C++ is designed to allow you to express ideas directly in code. If you can think of it, you should be able to express it in C++."
"Leave no room for a lower-level language below C++ (except assembler)."
"What you don't use, you don't pay for. What you do use, you couldn't hand-code any better."
Design Principles
Direct Mapping to Hardware: C++ abstractions should map efficiently to hardware. No hidden costs, no magic.
Zero-Overhead Abstraction: Abstractions must not impose runtime costs beyond what a careful programmer would write by hand.
Type Safety as Foundation: The type system is your ally. Use it to catch errors at compile time, not runtime.
Resource Management via RAII: Every resource acquisition should be tied to object lifetime. No manual cleanup.
Express Intent Clearly: Code should say what it means. Prefer declarative over clever.
When Writing Code
Always
- Use RAII for all resource management (memory, files, locks, connections)
- Prefer compile-time checking to runtime checking
- Use the type system to make illegal states unrepresentable
- Initialize variables at point of declaration
- Prefer
const by default—mutability should be the exception
- Use standard library algorithms over hand-written loops
- Design classes with clear invariants
Never
- Use raw
new/delete in application code (use smart pointers, containers)
- Leave resources unmanaged (no naked pointers to owned memory)
- Use C-style casts (use
static_cast, dynamic_cast, etc.)
- Ignore compiler warnings—they're often errors waiting to happen
- Write "clever" code that sacrifices clarity for brevity
- Use macros where
constexpr, templates, or inline suffice
Prefer
std::unique_ptr over std::shared_ptr unless sharing is truly needed
std::string_view over const std::string& for read-only string parameters
std::span over pointer+size pairs
- Structured bindings for multiple return values
- Range-based for loops over index-based iteration
constexpr over runtime computation when possible
- Concepts over SFINAE for template constraints (C++20+)
Code Patterns
Resource Management (RAII)
// BAD: Manual resource management
void process_file_bad(const char* filename) {
FILE* f = fopen(filename, "r");
if (!f) return;
// ... what if exception thrown here?
fclose(f); // Easy to forget, impossible with exceptions
}
// GOOD: RAII via standard library
void process_file_good(const std::filesystem::path& filename) {
std::ifstream file(filename);
if (!file) return;
// File automatically closed when 'file' goes out of scope
// Exception-safe by construction
}
Type-Safe Interfaces
// BAD: Primitive obsession
void set_timeout(int milliseconds);
void set_timeout(int seconds); // Which is it?
// GOOD: Strong types express intent
class Milliseconds {
int value_;
public:
explicit Milliseconds(int v) : value_(v) {}
int count() const { return value_; }
};
void set_timeout(Milliseconds timeout);
// Usage: set_timeout(Milliseconds{500}); // Clear and type-safe
Const Correctness
class Buffer {
std::vector<std::byte> data_;
public:
// Const method: promises not to modify state
std::span<const std::byte> view() const { return data_; }
// Non-const: may modify
std::span<std::byte> data() { return data_; }
// Return by value for computed results (enables move semantics)
std::vector<std::byte> compressed() const;
};
Mental Model
Stroustrup thinks of C++ as a tool for direct expression of ideas with predictable performance. When writing code:
- Model the domain: What are the key abstractions? What invariants must hold?
- Leverage the type system: Make incorrect usage a compile error
- Consider resource lifetime: Who owns what? When is it released?
- Measure, don't assume: Profile before optimizing
Evolution
Stroustrup's thinking has evolved with the language:
- C++11: "Modern C++" begins—move semantics, smart pointers, lambdas
- C++17: Structured bindings,
std::optional, std::variant
- C++20: Concepts finally arrive, coroutines, ranges
- C++23+: Continued refinement toward safety and expressiveness
Additional Resources
- For detailed philosophy, see philosophy.md
- For references (books, talks), see references.md
1---2name: stroustrup-cpp-style3description: Write C++ code in the style of Bjarne Stroustrup, creator of C++. Emphasizes type safety, resource management via RAII, zero-overhead abstractions, and direct hardware mapping. Use when designing C++ systems, APIs, or when clarity and efficiency must coexist.4---5
6# Bjarne Stroustrup Style Guide
7
8## Overview
9
10Bjarne Stroustrup created C++ in 1979 at Bell Labs, evolving it from "C with Classes" into the multi-paradigm language used in systems from browsers to databases to operating systems. His philosophy shapes not just the language but how serious C++ is written.
11
12## Core Philosophy
13
14> "C++ is designed to allow you to express ideas directly in code. If you can think of it, you should be able to express it in C++."
15
16> "Leave no room for a lower-level language below C++ (except assembler)."
17
18> "What you don't use, you don't pay for. What you do use, you couldn't hand-code any better."
19
20## Design Principles
21
221. **Direct Mapping to Hardware**: C++ abstractions should map efficiently to hardware. No hidden costs, no magic.
23
242. **Zero-Overhead Abstraction**: Abstractions must not impose runtime costs beyond what a careful programmer would write by hand.
25
263. **Type Safety as Foundation**: The type system is your ally. Use it to catch errors at compile time, not runtime.
27
284. **Resource Management via RAII**: Every resource acquisition should be tied to object lifetime. No manual cleanup.
29
305. **Express Intent Clearly**: Code should say what it means. Prefer declarative over clever.
31
32## When Writing Code
33
34### Always
35
36- Use RAII for all resource management (memory, files, locks, connections)
37- Prefer compile-time checking to runtime checking
38- Use the type system to make illegal states unrepresentable
39- Initialize variables at point of declaration
40- Prefer `const` by default—mutability should be the exception
41- Use standard library algorithms over hand-written loops
42- Design classes with clear invariants
43
44### Never
45
46- Use raw `new`/`delete` in application code (use smart pointers, containers)
47- Leave resources unmanaged (no naked pointers to owned memory)
48- Use C-style casts (use `static_cast`, `dynamic_cast`, etc.)
49- Ignore compiler warnings—they're often errors waiting to happen
50- Write "clever" code that sacrifices clarity for brevity
51- Use macros where `constexpr`, templates, or `inline` suffice
52
53### Prefer
54
55- `std::unique_ptr` over `std::shared_ptr` unless sharing is truly needed
56- `std::string_view` over `const std::string&` for read-only string parameters
57- `std::span` over pointer+size pairs
58- Structured bindings for multiple return values
59- Range-based for loops over index-based iteration
60- `constexpr` over runtime computation when possible
61- Concepts over SFINAE for template constraints (C++20+)
62
63## Code Patterns
64
65### Resource Management (RAII)
66
67```cpp
68// BAD: Manual resource management
69void process_file_bad(const char* filename) {
70 FILE* f = fopen(filename, "r");
71 if (!f) return;
72 // ... what if exception thrown here?
73 fclose(f); // Easy to forget, impossible with exceptions
74}
75
76// GOOD: RAII via standard library
77void process_file_good(const std::filesystem::path& filename) {
78 std::ifstream file(filename);
79 if (!file) return;
80 // File automatically closed when 'file' goes out of scope
81 // Exception-safe by construction
82}
83```
84
85### Type-Safe Interfaces
86
87```cpp
88// BAD: Primitive obsession
89void set_timeout(int milliseconds);
90void set_timeout(int seconds); // Which is it?
91
92// GOOD: Strong types express intent
93class Milliseconds {
94 int value_;
95public:
96 explicit Milliseconds(int v) : value_(v) {}
97 int count() const { return value_; }
98};
99
100void set_timeout(Milliseconds timeout);
101// Usage: set_timeout(Milliseconds{500}); // Clear and type-safe
102```
103
104### Const Correctness
105
106```cpp
107class Buffer {
108 std::vector<std::byte> data_;
109public:
110 // Const method: promises not to modify state
111 std::span<const std::byte> view() const { return data_; }
112
113 // Non-const: may modify
114 std::span<std::byte> data() { return data_; }
115
116 // Return by value for computed results (enables move semantics)
117 std::vector<std::byte> compressed() const;
118};
119```
120
121## Mental Model
122
123Stroustrup thinks of C++ as a tool for **direct expression of ideas** with **predictable performance**. When writing code:
124
1251. **Model the domain**: What are the key abstractions? What invariants must hold?
1262. **Leverage the type system**: Make incorrect usage a compile error
1273. **Consider resource lifetime**: Who owns what? When is it released?
1284. **Measure, don't assume**: Profile before optimizing
129
130## Evolution
131
132Stroustrup's thinking has evolved with the language:
133- **C++11**: "Modern C++" begins—move semantics, smart pointers, lambdas
134- **C++17**: Structured bindings, `std::optional`, `std::variant`
135- **C++20**: Concepts finally arrive, coroutines, ranges
136- **C++23+**: Continued refinement toward safety and expressiveness
137
138## Additional Resources
139
140- For detailed philosophy, see [philosophy.md](philosophy.md)
141- For references (books, talks), see [references.md](references.md)