size_t + ptrdiff_t

Artur Skawina art.08.09 at
Mon Feb 20 10:07:33 PST 2012

On 02/20/12 13:32, Stewart Gordon wrote:
> On 20/02/2012 03:44, Artur Skawina wrote:
> <snip>
>>> Why would you want to do that, as opposed to use one of the pointer types (which is
>>> indeed required for GC to work correctly)?
>> That's how it can be used in *C*.
>> And the reason it needs to be exposed to D code is for interoperability with C.
> IINM, C calling conventions care only about the size of a type, not the name or intrinsic nature of it.  Therefore this is a non-issue.

struct S { uintptr_t a; };
extern (C) uintptr_t f(S* s, uintptr_t* blah);

"uintptr_t" is not the best example here (because it will rarely appear in C
APIs), but still shows the problem - you need to know what it is - otherwise
you're left with guessing and eg assuming that uintptr==size_t.

Fixing historical mistakes can be hard.

There are basically three types of integer types:

a) known fixed size types, such as a 32-bit wide unsigned int
b) types, that are not explicitly sized, but meet certain criteria,
     eg: sizeof(short)<=sizeof(int)<=sizeof(long)
c) externally defined types, which must always have the same representation,
    the above uintptr_t example falls into this category.

'C' didn't have the (a) types, so everybody had to redefine u8/s16/u32/s64 etc.
'D' added these as builtin types so that problem was solved. Unfortunately, 
instead of eg using the de facto std s16/s32/s64, D reused short/int/long.
'C's short/int/long were poorly (too loosely) defined, but what should have
been done is defining them in 'D' as, for example:

int:  efficient integer type, fitting in a CPU register and at least 32 bit wide;
long: efficient integer type, fitting in a CPU register and as wide as a GPR.

Fixing things up now, with for example "nativeInt" (maps to "int" above) and
"widestInt" (the "long" above), is not easy. They are needed, that's why
threads like this one appear, but simply adding them to the language or std
library [1] wouldn't be enough. Why? Think literals, promotion and auto --
I'm afraid programmers working with 'native' ints may not be expecting
expressions evaluating to a narrower type.

So there probably is no ideal simple solution for D2. For 64-bit platforms and
a future D3 language, the int/long, as defined above, would be a mostly backward
compatible change.


[1] fundamental types like these should not require any imports, so object.d
    and/or compiler is the best place for them.

More information about the Digitalmars-d mailing list