On 20 February 2012 20:07, Artur Skawina <art.08.09@gmail.com> wrote:
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;

No, this would be very very bad. People would use 'int' out of habit in data structures, and mess up binary compatibility and alignment rules.
I personally quite like D's int types as they are, but note there are some 'missing' (well, not missing, as we're discussing, but they are not well defined, or named, and needlessly aliased)
 
long: efficient integer type, fitting in a CPU register and as wide as a GPR.

I don't think the term 'long' here, as opposed to 'int' draws this distinction... so I really can't buy into this logic.
 
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.

I prefer to explicitly identify these types personally. Predictable sized types are better to have people punching away with no real consideration to the specific use case.
People should only use these resizing types deliberately when they know what they're doing.
 
artur

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