| name | cpp-modern-style |
| description | Modern C++23 coding style and conventions for RedSalamander. Use when writing new code, reviewing style, using STL containers, smart pointers, std::format, std::optional, or following naming conventions. |
| metadata | {"author":"RedSalamander","version":"1.0"} |
Modern C++23 Style Guide
Project Requirements
- C++23 standard
- Unicode UTF-16 encoding
- Windows 10/11 minimum
Smart Pointers
std::unique_ptr<Widget> widget = std::make_unique<Widget>();
std::shared_ptr<Resource> resource = std::make_shared<Resource>();
Widget* widget = new Widget();
delete widget;
STL Usage
auto msg = std::format(L"Found {} files", count);
std::optional<int> result = FindValue();
if (result.has_value()) {
Use(result.value());
}
int val = result.value_or(0);
for (const auto& item : items) { }
auto [key, value] = GetPair();
wchar_t buf[256];
Formatting Into Fixed Buffers (When Required)
Prefer std::format_to_n over *printf_s when you must write into an existing fixed buffer (e.g. noexcept hot paths, Win32 APIs).
std::array<wchar_t, 32> buf{};
constexpr size_t max = buf.size() - 1;
const auto r = std::format_to_n(buf.data(), max, L"VK_{:02X}", vk);
buf[(r.size < max) ? r.size : max] = L'\0';
Naming Conventions
| Type | Style | Example |
|---|
| Classes | PascalCase | ColorTextView |
| Public methods | PascalCase | RenderText() |
| Private methods | camelCase | calculateLayout() |
| Variables | camelCase | textLayout |
| Members | _ prefix | _scrollY |
| Constants | kName | kMaxBufferSize |
Code Style
int width;
int height;
int width, height;
auto iter = container.begin();
constexpr int kBufferSize = 1024;
void Process(std::wstring_view text);
void Process(std::span<const int> data);
C++ Core Guidelines
Follow C++ Core Guidelines:
- Prioritize safety, simplicity, and maintainability
- Avoid undefined behavior
- Use GSL concepts where applicable
RAII Pattern
Every resource should have an owner:
class Resource
{
Handle _handle;
public:
Resource(Args args) : _handle(acquire(args)) {}
~Resource() { release(_handle); }
Resource(const Resource&) = delete;
Resource& operator=(const Resource&) = delete;
Resource(Resource&&) noexcept = default;
Resource& operator=(Resource&&) noexcept = default;
};
File Organization
- Headers: Keep interfaces minimal, use forward declarations
- Implementation: Group related functionality together
- Dependencies: Minimize header includes
- Platform: Isolate platform-specific code when possible
Comments and Documentation
- Write self-documenting code with meaningful names
- Document public APIs with Doxygen-style comments
- Explain "why" rather than "what"
- Include performance notes for critical sections
- For perf-sensitive features or hot-path changes, define the protected scenario and required measurement path in code/docs early rather than after the implementation is complete
Patterns to Avoid
new/delete (use smart pointers)
- C-style casts (use
static_cast, reinterpret_cast)
goto (use early returns + RAII / wil::scope_exit)
- Raw Windows handles (use WIL wrappers)
sprintf_s / swprintf_s in non-PoC code
catch (...) (FORBIDDEN; catch explicitly named exception types only, and document why catching is mandatory at that boundary)
- Global state and singletons unless absolutely necessary
- Blocking UI thread with synchronous operations
- String concatenation in loops (use
std::format or reserve capacity)
- Multiple variable declarations on same line
- Perf-sensitive feature work with no instrumentation, no deterministic selftest, or no archived evidence