From 3e80bd2cfd28ea54c2be8abe23442daa55c53e84 Mon Sep 17 00:00:00 2001 From: Ivar Fatland Date: Fri, 10 Oct 2025 20:13:15 +0200 Subject: [PATCH] with_borrow macros this allows for scope-based heap allocations. There is one limitation. You cannot use the return keyword inside the following block. This trick uses dark macro magic :) --- allocator.h | 11 +++++++++++ test_borrow_allocator.c | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/allocator.h b/allocator.h index f70e243..289374d 100644 --- a/allocator.h +++ b/allocator.h @@ -86,6 +86,17 @@ size_t borrow_allocator_count_allocations(borrow_allocator_t *this); void borrow_allocator_assert_all_freed(borrow_allocator_t *this); allocator_t borrow_allocator_interface(borrow_allocator_t *this); +// Some text that can be used as an identifier (no, not by you), so that I can +// use a variable that won't collide with yours inside macros. +#define UNIQUE __macro_internal_34bba35b8b9b20a75f9881e3795630e25d36e620d9c9741e2e9141ba82ec6ef6__ + +// Using the return a keyword in the statement following this macro will cause +// a guaranteed memory leak. +#define with_borrow(NAME) \ + borrow_allocator_t UNIQUE = borrow_allocator_create(); \ + for (allocator_t NAME = borrow_allocator_interface(&UNIQUE); !UNIQUE.head; UNIQUE.head = (borrow_allocator_reset(&UNIQUE), (linked_allocation_node_t*) 1)) \ + for (int UNIQUE = 0; UNIQUE < 1; UNIQUE++) + #ifdef ALLOCATOR_IMPLEMENTATION void *allocator_alloc_func(allocator_t this, size_t bytes, const char *file, int line) { diff --git a/test_borrow_allocator.c b/test_borrow_allocator.c index e04e973..1e138aa 100644 --- a/test_borrow_allocator.c +++ b/test_borrow_allocator.c @@ -12,3 +12,12 @@ Test(borrow_allocator, test) { cr_assert_eq(0, borrow_allocator_count_allocations(&balloc)); borrow_allocator_assert_all_freed(&balloc); } + + +Test(borrow_allocator, with) { + with_borrow(foo) { + allocator_alloc(foo, 1000); + allocator_alloc(foo, 100); + allocator_alloc(foo, 90); + } +}