I think the answer of rwong above already excellently highlights the issues.
I'll add my 002:
size_t
, that is, a size that ...can store the maximum size of a theoretically possible object of any type (including array).
... is only required for range indices when
sizeof(type)==1
, that is, if you're dealing with byte (char
) types. (But, we note, ttit can be smaller than a ptr type:As such,
xxx::size_type
could be used in 99.9% cases even if it were a signed sized type. (comparessize_t
)The fact that
std::vector
and friends chosesize_t
, an unsigned type, for the size and indexing is considered by some to be a design flaw. I concur. (Seriously, take 5 minutes and watch the lightning talk CppCon 2016: Jon Kalb “unsigned: A Guideline for Better Code".)When you design an C++ API today, you're in a tight place: Use
size_t
to be consistent with the Standard Library, or use (a signed)intptr_t
orssize_t
for easy and less bug prone indexing calculations.Don't use int32 or int64 - use
intptr_t
if you want to go signed, and want machine word size, or usessize_t
.
To directly answer the question, it is not entirely an "historical artefact", as the theoretical issue of needing to address more than half the ("indexing", or) address space must be, aehm, addressed somehow in a low level language like C++.
In hindsight, I, personally, think, it is a design flaw that the Standard Library uses unsigned size_t
all over the place even where it does not represent a raw memory size, but a capacity of typed data, like for the collections:
- given C++s integer promotion rules ->
- unsigned types just don't make good candidates for "semantic" types for something like a size that is semantically unsigned.
I'll repeat Jon's advice here:
- Select types for the operations they support (not the range of values). (*1)
- Don't use unsigned types in you API. This hides bugs with no upside benefit.
- Don't use "unsigned" for quantities.(*2)
(*1) i.e. unsigned == bitmask, never do math on it (here hits the first exception - you may need a counter that wraps - this must be an unsigned type.)
(*2) quantities meaning something you count and/or do math on.