I think that works on some architectures but would not be guaranteed behavior.  In theory on a system with no memory ordering constraints, the pointers could update before the cache lines for the underlying ring buffer.  Which means that without an acquire barrier at the beginning of aring_take, which without an item count, would require writes to the shared head&#x2F;tail pointers to sync anyway, you can&#x27;t ensure the the data written to the ring buffer is visible to the thread, even though your pointers would indicate there&#x27;s data there and so you may load either torn or completely different data into the consumer thread.<p>Which means that if your memory barriers are operating correctly, they&#x27;re just causing two cache lines to sync for the metadata instead of one, if the pointers are split across two lines.<p>Whereas with an item count, only one line ever has to sync, even if the pointers are split across two, since the pointers aren&#x27;t shared between threads.<p>In practice, the compiler might not be smart enough to realize this and might be enforcing order for all side effects before the barriers though, even if the other thread doesn&#x27;t read them.  So maybe this isn&#x27;t a good approach.