February 22, 2012
On Feb 21, 2012, at 3:50 PM, Juan Manuel Cabo wrote:

>> Eh?
> 
> All the type sizes vary in broken ways in C. The only sane way
> to port C structs to D is to use c_<type> that has the size of the
> C compiler in the target platform.
> 
> If there is a single C compiler has a different sized size_t
> than D's, then one has achieved nothing with the c_int, c_long, etc.
> 
> So that is why it'd be nice, in my opinion, to have c_size_t (and c_ssize_t) if we are going to have c_int, c_long, etc.

size_t is intended to be the C representation.  I very much do not want to end up with a c_size_t.  Are there times when D's size_t would be a different type?  Also, I wonder how much code would break if we eliminated the size_t in object.di and replaced it with Size or whatever.
February 22, 2012
> size_t is intended to be the C representation.  I very much do not want to end up with a c_size_t.

Hahah, hold your jaw because it might drop:

Looking for size_t extravagancies in C, I found that VC uses __int64 for size_t in x64 target.

So this behaves differently according to the target:

       size_t s = -2;
       if (s < -1) {
           printf("An supposedly unsigned size_t is less than -1 in x64 ??");
       } else {
           printf("all good, size_t is still unsigned");
       }

Though I don't ever expect to see a VC backend for D, this shows that
anything can be expected from C.
If you want to keep D's size_t unsigned, then let c_size_t do whatever C does,
and let D use sane types that do what the documentation says.

:-)

--jm


On 02/21/2012 09:10 PM, Sean Kelly wrote:
> On Feb 21, 2012, at 3:50 PM, Juan Manuel Cabo wrote:
> 
>>> Eh?
>>
>> All the type sizes vary in broken ways in C. The only sane way
>> to port C structs to D is to use c_<type> that has the size of the
>> C compiler in the target platform.
>>
>> If there is a single C compiler has a different sized size_t
>> than D's, then one has achieved nothing with the c_int, c_long, etc.
>>
>> So that is why it'd be nice, in my opinion, to have c_size_t (and c_ssize_t) if we are going to have c_int, c_long, etc.
> 
> size_t is intended to be the C representation.  I very much do not want to end up with a c_size_t.  Are there times when D's size_t would be a different type?  Also, I wonder how much code would break if we eliminated the size_t in object.di and replaced it with Size or whatever.

February 22, 2012
I'm sorry, my snippet is wrong. It's a bit more complicated than what I first thought, and not even uniform between VC versions:

   "size_t definition and C4267 warning"
   social.msdn.microsoft.com/forums/en-US/vclanguage/thread/62d6df45-e8e4-4bb2-87e2-b3f8e85b4b37

--jm


On 02/21/2012 09:50 PM, Juan Manuel Cabo wrote:
>> size_t is intended to be the C representation.  I very much do not want to end up with a c_size_t.
> 
> Hahah, hold your jaw because it might drop:
> 
> Looking for size_t extravagancies in C, I found that VC uses __int64 for size_t in x64 target.
> 
> So this behaves differently according to the target:
> 
>        size_t s = -2;
>        if (s < -1) {
>            printf("An supposedly unsigned size_t is less than -1 in x64 ??");
>        } else {
>            printf("all good, size_t is still unsigned");
>        }
> 
> Though I don't ever expect to see a VC backend for D, this shows that
> anything can be expected from C.
> If you want to keep D's size_t unsigned, then let c_size_t do whatever C does,
> and let D use sane types that do what the documentation says.
> 
> :-)
> 
> --jm
> 
> 
> On 02/21/2012 09:10 PM, Sean Kelly wrote:
>> On Feb 21, 2012, at 3:50 PM, Juan Manuel Cabo wrote:
>>
>>>> Eh?
>>>
>>> All the type sizes vary in broken ways in C. The only sane way
>>> to port C structs to D is to use c_<type> that has the size of the
>>> C compiler in the target platform.
>>>
>>> If there is a single C compiler has a different sized size_t
>>> than D's, then one has achieved nothing with the c_int, c_long, etc.
>>>
>>> So that is why it'd be nice, in my opinion, to have c_size_t (and c_ssize_t) if we are going to have c_int, c_long, etc.
>>
>> size_t is intended to be the C representation.  I very much do not want to end up with a c_size_t.  Are there times when D's size_t would be a different type?  Also, I wonder how much code would break if we eliminated the size_t in object.di and replaced it with Size or whatever.
> 

February 22, 2012
On Feb 21, 2012, at 4:50 PM, Juan Manuel Cabo wrote:

>> size_t is intended to be the C representation.  I very much do not want to end up with a c_size_t.
> 
> Hahah, hold your jaw because it might drop:
> 
> Looking for size_t extravagancies in C, I found that VC uses __int64 for size_t in x64 target.

I think this is actually a good thing, since working with unsigned integers is a pain.  I can't see any system needing that extra bit to represent size any time soon anyway.
February 22, 2012
On 21/02/2012 22:45, Juan Manuel Cabo wrote:
<snip>
> The C standard only guarantees that:
>
>    sizeof(char)<= sizeof(int)<= sizeof(long)<= sizeof(size_t)
<snip>

I'm surprised.  I'd assumed that, under 16-bit DOS/Windows, a size_t would be 16 bits. But no.  Could memory blocks 64K or larger actually be allocated under those systems?

Stewart.
February 22, 2012
On 02/21/2012 10:13 PM, Sean Kelly wrote:
> I think this is actually a good thing, since working with unsigned integers is a pain.

Yes, I would prefer that msb bit to be the sign too, but behavior might depend on it, and correctness and predictability is important.

My first code snippet was WRONG (sorry for the noise). And I couldn't even reproduce the problem with my VC.

A correct snippet is simply this:

    size_t s = -2;

    if (s > 0) {
         printf("unsigned");
    } else {
         printf("signed");
    }

Also, the shift operator is does a logical or arithmetic shift depending
on whether it is signed or unsigned, so the result is different
if you do
     s >> 1
whether s is signed or unsigned.

THis is already nitpicky. I'm sorry for the noise.

--jm



February 22, 2012
I just went to see a standard draft (http://www.clc-wiki.net/wiki/the_C_Standard)
to make sure, and it is even more convoluted than just that, but essentially the
same. Basically it says that chars must be at least
8bits and that shorts and ints must be able to represent at least 16 bits.

Then the ranks of the types are related to each other like that:
    rank(_Bool) < rank(char) < rank(short) < rank(int) < rank(long int) < rank(long long int)
but rank is about conversion, not size, so while rank is strictly ordered,
sizeof types might not.

I didn't find size_t other than as the type of the value of sizeof() expressions.

So, size_t is just standardized as the type of (sizeof(anystuff)).

I saw sizeof(long) <= sizeof(size_t)  in a website, but not on the standard.
So the standard doesn't even guarantee size_t being more than other
types, or the bigger type.

--jm


On 02/21/2012 10:23 PM, Stewart Gordon wrote:
> On 21/02/2012 22:45, Juan Manuel Cabo wrote:
> <snip>
>> The C standard only guarantees that:
>>
>>    sizeof(char)<= sizeof(int)<= sizeof(long)<= sizeof(size_t)
> <snip>
> 
> I'm surprised.  I'd assumed that, under 16-bit DOS/Windows, a size_t would be 16 bits. But no.  Could memory blocks 64K or larger actually be allocated under those systems?
> 
> Stewart.

February 22, 2012
>> I'm surprised.  I'd assumed that, under 16-bit DOS/Windows, a size_t would
>> be 16 bits. But no.  Could memory blocks 64K  or larger actually be allocated under those systems?

size_t being the typeof sizeof() expressions, tell you the upper bound
for the size of static arrays, statically allocated: sizeof(buffer)/sizeof(int)
has to be representable in a size_t.

It tells you nothing else. What you can allocate dinamically depends on the architecture and how it lets you address it.

16bit intel had 16bit segments and offsets, so memory was segmented
and you couldn't address more than 64kb at a time.
So you couldn't have grabbed^H^H"allocated" more than 64kb in real mode in intel
in a single linear block.


--jm
February 22, 2012
On 2/21/2012 1:03 AM, Artur Skawina wrote:
> Types like ptrdiff_t are not necessary in D, because you can write portable
> code using 'auto' and 'typeof()' - std C didn't have these, so a type had
> to be invented for everything.

And, in fact, object.di contains:

alias typeof(int.sizeof)                    size_t;
alias typeof(cast(void*)0 - cast(void*)0)   ptrdiff_t;
February 22, 2012
On 2/21/2012 12:33 AM, Manu wrote:
> On 21 February 2012 01:22, Walter Bright <newshound2@digitalmars.com
> <mailto:newshound2@digitalmars.com>> wrote:
>
>     On 2/20/2012 3:28 AM, Manu wrote:
>
>         Even size_t is often
>         broken in C. I have worked on 64bit systems with 32bit pointers where
>         size_t was
>         still 64bit, but ptrdiff_t was 32bit (I think PS3 is like this, but maybe my
>         memory fails me)
>
>
>     I don't know how that could be considered C standard compliant.
>
>
> I don't know about you, but I very rarely get to work with a C compiler that is
> 'standards compliant'.. that concept is kinda like a cruel joke in my
> experience. Does one even exist? :)

The C99 Standard sez:

"The types are ptrdiff_t which is the signed integer type of the result of subtracting two pointers; size_t which is the unsigned integer type of the result of the sizeof operator;"

I don't know of any excuse for getting this wrong.