AgentStack
SKILL verified MIT Self-run

Cpp Rules

skill-softspark-ai-toolkit-cpp-rules · by softspark

C++ coding rules: style, patterns, security, testing. Triggers: .cpp, .cc, .cxx, .hpp, .h, CMakeLists.txt, Makefile, GoogleTest, clang-tidy.

No reviews yet
0 installs
18 views
0.0% view→install

Install

$ agentstack add skill-softspark-ai-toolkit-cpp-rules

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access Used
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Cpp Rules? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

C++ Rules

These rules come from app/rules/cpp/ in ai-toolkit. They cover the project's standards for coding style, frameworks, patterns, security, and testing in C++. Apply them when writing or reviewing C++ code.

C++ Coding Style

Naming

  • PascalCase: classes, structs, enums, type aliases, concepts.
  • camelCase or snake_case: functions, methods, variables (be consistent per project).
  • UPPER_SNAKE: macros, compile-time constants.
  • Prefix member variables with m_ or suffix with _ (pick one convention).
  • Namespace names: lowercase, short (namespace io, namespace util).

Modern C++ (17/20/23)

  • Use auto for iterator types and complex template deductions.
  • Use std::optional instead of sentinel values or pointers for optional returns.
  • Use std::variant over union types. Use std::visit for dispatch.
  • Use std::string_view for non-owning string parameters.
  • Use structured bindings: auto [key, value] = *map.begin();.
  • Use constexpr for compile-time evaluation. Prefer over macros.

Memory Management

  • Use RAII exclusively. Every resource acquisition is an initialization.
  • Use std::unique_ptr for exclusive ownership (default choice).
  • Use std::shared_ptr only when ownership is genuinely shared.
  • Never use raw new/delete. Use std::make_unique / std::make_shared.
  • Use std::span (C++20) for non-owning views over contiguous data.

Functions

  • Pass small types by value. Pass large types by const&.
  • Use [[nodiscard]] on functions whose return value must not be ignored.
  • Use noexcept on functions that do not throw (move constructors, destructors).
  • Limit function parameters to 4. Use structs for configuration objects.
  • Use trailing return types for complex template return deductions.

Includes and Dependencies

  • Use #pragma once or include guards. Prefer #pragma once for simplicity.
  • Order: corresponding header, C++ stdlib, third-party, project headers.
  • Forward-declare in headers when possible to reduce compile times.
  • Minimize header dependencies. Use the Pimpl idiom for ABI stability.

Avoid

  • Raw pointers for ownership. Use smart pointers.
  • C-style casts. Use static_cast, dynamic_cast, const_cast.
  • Macros for constants or functions. Use constexpr and templates.
  • using namespace std; in headers. Acceptable in .cpp files with caution.
  • std::endl -- use '\n' (endl flushes the buffer unnecessarily).

Formatting

  • Use clang-format with a committed .clang-format file.
  • Use clang-tidy for static analysis and automated modernization.
  • Max line length: 100-120 characters.
  • Braces: use Allman or K&R consistently per project.

C++ Frameworks

CMake

  • Use modern CMake (3.14+): target-based, not directory-based.
  • Use target_link_libraries with PUBLIC/PRIVATE/INTERFACE visibility.
  • Use FetchContent for dependency management. Avoid manual submodule vendoring.
  • Set CMAKE_CXX_STANDARD 20 (or 23) at the project level.
  • Use target_compile_options for per-target flags, not global add_compile_options.
  • Export targets with install(TARGETS ... EXPORT ...) for library consumers.

Boost

  • Use Boost.Asio for async networking and I/O.
  • Use boost::beast for HTTP/WebSocket built on Asio.
  • Use boost::json or nlohmann/json for JSON parsing.
  • Prefer C++ stdlib equivalents when available (e.g., std::optional over boost::optional).
  • Link only the Boost libraries you actually use. Many are header-only.

Qt

  • Use signals and slots for event-driven communication.
  • Use QObject parent-child ownership for automatic memory management.
  • Use QML for declarative UI. Keep business logic in C++ backend.
  • Use QThread with worker objects (moveToThread), not subclassing QThread.
  • Use smart pointers for non-QObject resources. QObject children are auto-deleted.

gRPC

  • Define services in .proto files. Generate C++ stubs with protoc.
  • Use async server with CompletionQueue for high-throughput services.
  • Use grpc::ClientContext for per-call deadlines and metadata.
  • Use interceptors for logging, auth, and metrics.
  • Set deadlines on every RPC call to prevent hanging.

Networking (Asio)

  • Use io_context as the event loop. Run from one or more threads.
  • Use co_await (C++20 coroutines) with Asio for clean async code.
  • Use strand for serializing access to shared state across handlers.
  • Use steady_timer for timeouts and periodic tasks.
  • Handle errors via error_code parameter, not exceptions, in async callbacks.

Database

  • Use libpq (PostgreSQL) or SOCI for database access.
  • Use prepared statements exclusively. Never concatenate SQL strings.
  • Use connection pooling for multi-threaded server applications.
  • Use SQLite via sqlite3 C API with RAII wrappers for embedded use cases.

Package Management

  • Use vcpkg or Conan 2 for dependency management.
  • Pin dependency versions in vcpkg.json or conanfile.py.
  • Use CI caching for build artifacts and dependency downloads.
  • Prefer pre-built binary packages for CI speed.

C++ Patterns

Error Handling

  • Use exceptions for truly exceptional conditions. Use return types for expected failures.
  • Use std::expected (C++23) or Result pattern for recoverable errors.
  • Use std::error_code / std::error_category for system-level errors.
  • Use noexcept on functions that must not throw (destructors, move operations).
  • Catch by const&. Never catch by value (slicing) or pointer.

RAII Patterns

  • Wrap every resource (memory, file, lock, socket) in an RAII type.
  • Use std::lock_guard or std::scoped_lock for mutex management.
  • Use std::unique_lock when deferred locking or condition variables are needed.
  • Use std::fstream (auto-closes) instead of fopen/fclose.
  • Write custom RAII wrappers for C library resources (file descriptors, handles).

Smart Pointer Patterns

  • unique_ptr: default ownership model. Transfer with std::move.
  • shared_ptr: use only for genuinely shared ownership graphs.
  • weak_ptr: break cycles in shared_ptr graphs. Use lock() to access.
  • Factory functions should return unique_ptr. Let callers upgrade to shared_ptr.
  • Never pass smart pointers by reference. Pass T& or T* to non-owning consumers.

Concurrency

  • Use std::thread with std::jthread (C++20) for auto-joining threads.
  • Use std::mutex + std::scoped_lock for shared data protection.
  • Use std::atomic for lock-free single-variable synchronization.
  • Use std::condition_variable for producer-consumer patterns.
  • Use std::async / std::future for simple parallel computation.
  • Use std::counting_semaphore (C++20) for resource pool limiting.

Template Patterns

  • Use CRTP for compile-time polymorphism (static dispatch).
  • Use concepts (C++20) to constrain template parameters with clear error messages.
  • Use if constexpr for compile-time branching in templates.
  • Use variadic templates and fold expressions for parameter packs.
  • Prefer constexpr functions over template metaprogramming when possible.

Design Patterns

  • Use std::variant + std::visit for type-safe visitor pattern.
  • Use std::function for type-erased callbacks and strategy pattern.
  • Use Pimpl idiom (unique_ptr) for ABI stability and compilation firewall.
  • Use Builder pattern with method chaining for complex object construction.
  • Use std::move semantics in move constructors for efficient resource transfer.

Anti-Patterns

  • Raw new/delete: use smart pointers and containers.
  • Returning raw pointers from factory functions: return unique_ptr.
  • const_cast to remove constness: redesign the interface.
  • Deep inheritance hierarchies: prefer composition and templates.
  • Premature optimization over readability: profile first, optimize second.

C++ Security

Buffer Overflow Prevention

  • Use std::string, std::vector, std::array instead of C arrays and char[].
  • Use std::span (C++20) for safe, bounds-checked views over contiguous data.
  • Never use strcpy, strcat, sprintf. Use std::string operations or snprintf.
  • Enable -D_FORTIFY_SOURCE=2 in release builds for runtime buffer checks.
  • Use at() for bounds-checked container access in untrusted input paths.

Memory Safety

  • Use smart pointers exclusively. Zero raw new/delete in application code.
  • Enable AddressSanitizer (-fsanitize=address) in development and CI builds.
  • Enable UndefinedBehaviorSanitizer (-fsanitize=undefined) in test builds.
  • Use -fstack-protector-strong for stack buffer overflow detection.
  • Use Valgrind for memory leak detection in integration tests.

Integer Safety

  • Check for overflow before arithmetic on untrusted integers.
  • Use std::numeric_limits::max() for boundary checks.
  • Use unsigned types only for bit manipulation. Prefer signed for arithmetic.
  • Use static_cast explicitly. Never rely on implicit narrowing conversions.
  • Enable -Wconversion and -Wsign-conversion warnings.

Input Validation

  • Validate all external input: file data, network packets, command-line arguments.
  • Use std::stoi / std::stol with exception handling for string-to-number conversion.
  • Set maximum sizes for dynamic allocations based on untrusted input.
  • Validate file paths to prevent directory traversal (../).
  • Use allowlist validation for format specifiers and command strings.

Secure Coding

  • Use std::fill or explicit_bzero() to zero sensitive memory before deallocation.
  • Use constant-time comparison for secrets (avoid timing side-channels).
  • Use mlock() to prevent sensitive memory from being swapped to disk.
  • Compile with -fPIE -pie for position-independent executables (ASLR).
  • Enable -Werror in CI to prevent warnings from becoming vulnerabilities.

Dependencies

  • Audit third-party C libraries for known CVEs before inclusion.
  • Use vcpkg or Conan with pinned versions for reproducible builds.
  • Prefer well-maintained libraries with active security response teams.
  • Minimize C library usage. Prefer C++ standard library equivalents.

Concurrency Safety

  • Use std::mutex with std::scoped_lock for all shared data access.
  • Use std::atomic for lock-free single-variable operations.
  • Enable ThreadSanitizer (-fsanitize=thread) in test builds for race detection.
  • Avoid volatile for synchronization. It does not provide atomicity or ordering.
  • Use RAII lock guards. Never manually lock()/unlock().

Compiler Hardening

  • Enable all warnings: -Wall -Wextra -Wpedantic.
  • Use -D_GLIBCXX_ASSERTIONS for debug iterator and container checks.
  • Use -fno-exceptions only when exception safety is not required.
  • Link with -Wl,-z,relro,-z,now for full RELRO (GOT hardening).

C++ Testing

Framework

  • Use GoogleTest (gtest) as the primary test framework.
  • Use GoogleMock (gmock) for mocking interfaces and virtual classes.
  • Use Catch2 as a lightweight alternative (header-only, BDD-style).
  • Use CTest for test discovery and execution via CMake.

File Naming

  • Test files: foo_test.cpp or test_foo.cpp in a dedicated tests/ directory.
  • Mirror source directory structure in test directory.
  • One test file per source file or logical component.
  • Use CMakeLists.txt with add_test() to register tests.

Structure (GoogleTest)

  • Use TEST(SuiteName, TestName) for simple tests.
  • Use TEST_F(FixtureName, TestName) for tests sharing setup/teardown.
  • Use SetUp() / TearDown() in fixtures for per-test initialization.
  • Keep tests focused: one logical assertion per test case.

Assertions

  • Use EXPECT_* (non-fatal) by default. Use ASSERT_* only when continuation is meaningless.
  • EXPECT_EQ, EXPECT_NE, EXPECT_LT, EXPECT_GT for comparisons.
  • EXPECT_TRUE, EXPECT_FALSE for boolean conditions.
  • EXPECT_THROW(expr, ExceptionType) for exception testing.
  • EXPECT_THAT(value, matcher) with gmock matchers for complex assertions.

Parameterized Tests

  • Use INSTANTIATE_TEST_SUITE_P with testing::Values(...) for value-parameterized tests.
  • Use testing::Combine() for multi-dimensional parameterization.
  • Use TYPED_TEST_SUITE for type-parameterized tests across template types.
  • Prefer parameterized tests over copy-pasting similar test bodies.

Mocking (GoogleMock)

  • Define mock classes: MOCK_METHOD(ReturnType, MethodName, (Args), (Qualifiers)).
  • Use EXPECT_CALL(mock, Method(matchers)).WillOnce(Return(value)).
  • Use NiceMock to suppress uninteresting call warnings.
  • Use StrictMock to fail on any unexpected call.
  • Use dependency injection (constructor) to pass mock objects.

Build Integration

  • Use FetchContent or find_package to integrate gtest in CMake.
  • Enable BUILD_TESTING option to conditionally include tests.
  • Use ctest --output-on-failure for CI runs.
  • Use sanitizers in test builds: -fsanitize=address,undefined.

Best Practices

  • Test edge cases: empty input, max values, null pointers, boundary conditions.
  • Use RAII test fixtures for resource cleanup (no manual teardown).
  • Avoid testing private methods directly. Test through public API.
  • Use valgrind or ASan/UBSan in CI to detect memory errors.
  • Keep tests fast: mock I/O and external dependencies.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.