> I meant the `countof(a)` macro
As mentioned earlier in the article, one goal is to use signed sizes as
much as possible, with usize only for special cases, mainly in external,
conventional interfaces (e.g. the VirtualAlloc prototype near the end). I
believe unsigned size_t was a major misstep in the design of C. We should
use ptrdiff_t instead, and sizeof/alignof/etc. should have evaluated to
ptrdiff_t. Many defects over the decades could have been avoided with this
small change. Occasionally unsigned sizes are needed, particularly in
embedded and kernel work, to operate on quantities near the size of an
address space, but these are unusual, special cases. The common cases
shouldn't pay for it.
Size calculations are hazardous ([1], [2]), and the frequent use of sizeof
in typical C (with malloc, realloc, etc.) is a common defect source. For
this reason, language design has universally moved away from manually
computing sizes, e.g. C++ operator new. It's pushed behind the scenes
where it can be performed carefully and correctly. That's what I've done
with my new() macro, so that normal code isn't operating on sizes, just
subscripts.
With size calculations moved into specialized code, there's little need
for the sizeof operator aside from computing array lengths, which is where
countof() comes in. By casting the result to a signed size, I can nip that
little language design flaw, and unsigned sizes practically disappear. One
less thing to worry about.
(Side note: Early this year I eventually settled on iz for ptrdiff_t and
uz for size_t/uintptr_t. They're concise, non-conflicting, and reflect the
new integer suffixes in C23 and C++23. My article won't change because it
snapshots where my thinking was in 2023.)
[1]: https://nullprogram.com/blog/2024/05/24/
[2]: https://nullprogram.com/blog/2017/07/19/