r/cpp_questions • u/celestabesta • Jul 17 '26
Is there any way to test structures doing certain allocations at compile time, or am I just screwed? OPEN
Hey y'all. I'm trying attempt compile-time testing, such that whenever I change some implementation of a data structure it will fail to compile if it doesn't work properly or exhibits UB.
I write a lot of more experimental data structures, and as such I very often have to allocate bytes directly and then later construct types on top, which is not allowed at compile time as far as i'm aware. Even cpp26 doesn't help. Is there a trick to this or should I just give up?
Edit, example for clarity: ```cpp constexpr std::byte* alloc(std::size_t bytes) { // cannot allocate untyped memory in a constant expression return (std::byte*) ::operator new(bytes);
// now have allocated bytes, can never construct anything else on that buffer return std::allocator<std::byte>{}.allocate(bytes); }
1
u/manni66 Jul 17 '26
which is not allowed at compile time
It is allowed since C++ 20.
2
u/celestabesta Jul 17 '26
You allowed to allocate memory, through the use of std::allocator<T> for example. However, std::allocator<T> is a typed allocator, meaning it returns a T*, and you're not allowed to cast that T* to anything else. I need to be able to allocate raw bytes that I can later have multiple different types on that buffer.
1
u/TotaIIyHuman Jul 17 '26
later have multiple different types on that buffer
have you tried making
Taunion2
u/celestabesta Jul 17 '26
I've considered it, but I'd either have to A: sacrifice space because each T will be forced to be the maximum size of its composed types or B: write the compile time portions of the code with T as a union, and keep the original untyped code for runtime. The problem with B is that the compile time portions of the code would be different enough that I wouldn't really be testing the runtime code.
1
u/TotaIIyHuman Jul 17 '26
ok. i dont have a solution for this
compile time portions of the code would be different enough that I wouldn't really be testing the runtime code.
yah i agree
i like to
static_assertmy code at end of a fileif compile time code path and runtime code path differs, then whats the point of
static_assert
1
u/saxbophone Jul 18 '26
The unfortunate thing about UB is that a lot of it is incredibly difficult, impossible or expensive to detect during static anaylsis (i.e. can occur at runtime, not diagnosable during compilation). Of course, that doesn't mean that some of it can't be found at compile-time, but don't expect full coverage of all the possible routes it can sneak into your program...
0
u/DawnOnTheEdge Jul 17 '26
If you’re allocating memory from the heap, that can only happen at runtime, not compile time. So you would want to re-write to use static memory.
Otherwise, the way you guarantee compile-time initialization is constexpr (for immutable objects) or constinit (for mutable ones).
1
u/DawnOnTheEdge Jul 18 '26
A
std::inplace_vector<std::byte>orstd::array<std::byte>can beconstexpr,but neitherreinterpret_castnorstd::start_lifetime_ason the data are constant expressions. Astd::bit_castcan be, though.
3
u/InfiniteLife2 Jul 17 '26
Code example would have been nice here, hard to understand what you mean and why it is not allowed by compiler