Playing randomly on godbolt (as one does) I found that std::vector::size()
is implemented as a difference of pointers while I was expecting it to just return a class data member. std::vector::capacity()
is similar. What is weird is that all other standard containers (except std::deque
) store the size as a data member. Even std::string
on libstdc++ and Microsoft's STL stores its size as a data members (on libc++ it looks like size info storage is optimized with SSO info, still the size is explicitly stored and not computed as difference of pointers).
Here is the godbolt link with all the containers' size on libc++, libstdc++ and microsoft's STL. Some excerpts below:
f_vec4: //std::vector<std::int32_t>
mov rax, qword ptr [rdi + 8]
sub rax, qword ptr [rdi]
sar rax, 2
ret
f_vec8: // std::vector<int64_t>
mov rax, qword ptr [rdi + 8]
sub rax, qword ptr [rdi]
sar rax, 3
ret
f_list:
mov rax, QWORD PTR [rdi+16]
ret
f_map:
mov rax, QWORD PTR [rdi+40]
ret
Why is std::vector::size
the only container size implemented as pointer difference while all other containers store their size? Is is something in the standard? Is it an optimization?
why is std::vector::size implemented in terms of pointers on all major standard library implementations?
Because it can be implemented in terms of pointer subtraction. And because the standard library implementers chose to do that.
Is is something in the standard?
No. I'm sure that it would be standard conforming to store the size as a member.
What is weird is that all other standard containers (except std::deque) store the size as a data member.
This is hardly surprising. No other data structure can use pointers as iterators besides an array.
std::string
is implemented as an array, so it could also use pointer subtraction. If it isn't done so, it is because the implementers chose to not do so. This may, or might not be due to convenience related to small string optimisation.