size_t vs uintptr_t

Walter Bright via Digitalmars-d digitalmars-d at puremagic.com
Tue Jun 14 14:59:32 PDT 2016


I recently remembered something I'd half-forgotten. A size_t is not guaranteed 
to be the same size as a pointer. A uintptr_t is.

size_t and uintptr_t are the same for all platforms that D currently supports. 
But this may not always hold true, and besides, it is better self-documenting 
when using uintptr_t for "holds a pointer" as opposed to size_t as "holds an 
offset to a pointer".

uintptr_t may be found in:

     import core.stdc.stdint : uintptr_t;

as it is part of Standard C.

When are they not the same?

1. In 16 bit code that supports the 'far' memory model, where pointers are a 
segment/offset pair and uintptr_t would be 32 bits and size_t 16. Of course, D 
does not support 16 bit code so this is irrelevant for D.

2. There is a memory model in the 32 bit x86 where segment/offset pairs are 
used, and uintptr_t would be >=48 bits and size_t 32. This is used sometimes in 
kernel programming.

3. Any system that would have some sort of banked switched memory scheme.

Ok, I admit these are not likely to emerge. But I'd like our code to be 
pedantically, nitpickingly correct, as well as self-documenting.

druntime/phobos pervasively misuse size_t. I've put in a PR to address some:

     https://github.com/dlang/phobos/pull/4430

=========================================================

A related issue is I see much code of the form:

     cast(size_t)ptr & 3

to check alignment. A better (possibly faster) method is:

     cast(uint)ptr & 3

because even 64 bit CPUs often operate faster with 32 bit operations (thanks to 
some research by Andrei).

=========================================================

Call to action: do things like:

     grep cast(size_t) *.d

to look for misuse, and submit PRs to fix!


More information about the Digitalmars-d mailing list