Skip to main content
1 of 5
Martin Ba
  • 7.7k
  • 7
  • 36
  • 57

I think the answer of rwong above already excellently highlights the issues.

I'll add what think are worth mentioning:

  • size_t, that is a size that covers the full available flat memory range of the C++ abstract machine is only required for range indices when sizeof(type)==1, that is, if you're dealing with byte (char) types.
  • As such, xxx::size_type could be used in 99.9% cases even if it were a signed machine word sized type.
  • The fact that std::vector and friends chose size_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 (the signed) intptr_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.

To directly answer the question, it is not entirely an "historical artefact", as the theoretical issue of needing to address more than half the 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.

Martin Ba
  • 7.7k
  • 7
  • 36
  • 57