ysaie

31 / ⚧ / code, music, art, games

──────────────────────────────
🌸 many-shaped creature
✨ too many projects
🚀 cannot be stopped
🌙 stayed up too late
:eggbug: eggbug enjoyer
──────────────────────────────
header image: chapter 8 complete from celeste
avatar: made using this character builder


📩 email
contact@echowritescode.dev

and i think kinda overengineered?


so here's how allocating uninitialized storage works:

  • there's ::operator new(std::size_t, std::align_val_t) for allocating raw bytes from the free store
  • and also ::operator delete(void *, std::align_val_t) for deallocating from the free store
  • there's a convenient type-safe wrapper for these functions that can also be optimized around more effectively called std::allocator. great!
  • the low-level functions are statically defined and global, meaning there is no reason for std::allocator to have any non-static methods...
  • ... for some reason, std::allocator has non-static methods, but ...
  • ... there's std::allocator_traits, which has the exact same interface, and is fully static, yay! but ...
  • ... those functions take an allocator as a parameter, meaning you still need an instance of the allocator to pass to them ...
  • ... and you can't necessarily substitute one instance of std::allocator for another, so you need the instance to be stored somewhere ...
  • ... so you need to keep an instance of an empty type around, so you can call functions on it that don't keep any state, because... this is where i'm confused??

now, i can understand why you might want a non-static allocator in some cases. if you have an allocator based on a memory-mapped file, for instance, you would want to keep a handle to the mapped file (or at least a pointer to the mapped memory) around, and that necessarily wouldn't be the same between two different instances of this allocator type.

i just struggle to understand why "type safe, easier to optimize wrapper around low level functionality" is conflated with "allowances for the very niche situations where you want a nonstandard allocator that make the interface more complicated". like, there could very easily be a stateless std::allocate_uninitialized_storage<T>(std::size_t) and std::deallocate_uninitialized_storage<T>(T *) that are called by std::allocator... and there's just not? idk.

waiting for somebody to comment that those functions exist but just have some weird name and my whole point is rendered moot


You must log in to comment.

in reply to @ysaie's post:

I believe the problem is std::allocator was designed with x86 memory segmentation in mind, a thing that no longer exists. Using it for anything else is a pain, because that's not what it's for, and it's so baked into the language they can't get rid of it.

(Not sure why stateful allocators are needed for that, so I might be completely wrong)