From b455e97db370cd7e70717564ecee3d5d1c255c38 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Sat, 23 Aug 2025 21:22:16 -0400 Subject: [PATCH] Add casting section to style guide --- style.md | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/style.md b/style.md index d04ca8c..b83315c 100644 --- a/style.md +++ b/style.md @@ -72,6 +72,26 @@ signal(SIGTERM, handler); - Use for performance measurements, statistics, and monitoring data - Never use for counts, sizes, or business logic +### Type Casting +- **Never use C-style casts** - they're unsafe and can hide bugs by performing dangerous conversions +- **Use C++ cast operators** for explicit type conversions with clear intent and safety checks +- **Avoid `reinterpret_cast`** - almost always indicates poor design; redesign APIs instead +- **Prefer no casts** - design APIs and use types that avoid casting entirely when possible + +```cpp +// Dangerous - C-style casts (NEVER DO THIS) +// int* ptr = (int*)malloc(sizeof(int)); // Unsafe +// int64_t id = (int64_t)some_pointer; // Dangerous pointer conversion +// BaseClass* base = (BaseClass*)derived; // Loses type safety + +// Acceptable C++ cast operators (use sparingly) +auto ptr = static_cast(malloc(sizeof(int))); // Explicit conversion +auto base = static_cast(derived_ptr); // Safe upcast +auto derived = dynamic_cast(base_ptr); // Runtime type checking +auto mutable_ptr = const_cast(const_ptr); // Remove const (rare) +auto addr = reinterpret_cast(ptr); // Low-level operations (very rare, delicate) +``` + ### Performance Focus - **Performance-first design** - optimize for the hot path - **Simple is fast** - find exactly what's necessary, strip away everything else @@ -99,9 +119,9 @@ signal(SIGTERM, handler); ### Variables and Functions - **snake_case** for all variables, functions, and member functions ```cpp -size_t used_bytes() const; -void add_block(size_t size); -uint32_t initial_block_size_; +int64_t used_bytes() const; +void add_block(int64_t size); +int32_t initial_block_size_; ``` ### Structs @@ -113,12 +133,12 @@ uint32_t initial_block_size_; ```cpp struct ArenaAllocator { // Public interface first - explicit ArenaAllocator(size_t initial_size = 1024); - void* allocate_raw(size_t size); + explicit ArenaAllocator(int64_t initial_size = 1024); + void* allocate_raw(int64_t size); private: // Private members after - uint32_t initial_block_size_; + int32_t initial_block_size_; Block* current_block_; }; ``` @@ -150,7 +170,7 @@ static const WeaselJsonCallbacks json_callbacks; - **Trailing underscore** for private member variables ```cpp private: - uint32_t initial_block_size_; + int32_t initial_block_size_; Block *current_block_; ``` @@ -206,7 +226,7 @@ std::unique_ptr parser; - **Delete copy operations** when inappropriate ```cpp struct ArenaAllocator { - explicit ArenaAllocator(size_t initial_size = 1024); + explicit ArenaAllocator(int64_t initial_size = 1024); // Copy construction is not allowed ArenaAllocator(const ArenaAllocator &) = delete; @@ -217,7 +237,7 @@ struct ArenaAllocator { ArenaAllocator &operator=(ArenaAllocator &&other) noexcept; private: - uint32_t initial_block_size_; + int32_t initial_block_size_; Block *current_block_; }; ``` @@ -431,7 +451,7 @@ When in doubt, consult the `man` page for the specific system call to see if it * @note Prints error to stderr and calls std::abort() if allocation fails */ template -T *realloc(T *ptr, uint32_t old_size, uint32_t new_size); +T *realloc(T *ptr, int32_t old_size, int32_t new_size); ``` ### Code Comments @@ -440,7 +460,7 @@ T *realloc(T *ptr, uint32_t old_size, uint32_t new_size); - **Thread safety** and ownership semantics ```cpp // Uses O(1) accumulated counters for fast retrieval -size_t total_allocated() const; +int64_t total_allocated() const; // Only Server can create connections - no public constructor Connection(struct sockaddr_storage addr, int fd, int64_t id,