I’ve implemented this pattern without locks or CAS in C++, and it works just fine.
I’m currently using this pattern in rust (although with fixed size) and it works really well. The best part is it bypasses the borrow checker since an index isn’t a reference. So no compile time lifetimes to worry about. It’s awesome for linked lists, which are otherwise painful in rust. Also it can sometimes allow a linked list with array like cache performance, since the underlying layout is an array.
That's a bug, not a feature. The two times I've had go to looking for a bug in the lower levels of Rend3/WGPU (which are 3D graphics libraries), they've involved some index table being corrupted. That's the only time I've needed a debugger.
I’m fine with the trade off, but yes, it can be a source of difficult bugs.
You could presumably use the same tricks the allocator is using to handle more concurrent threads, although I suspect that's not worth the time required.