Thread overview
Can't add ubytes together to make a ubyte... bug or feature?
Jan 19, 2016
Soviet Friend
Jan 19, 2016
Daniel Kozak
Jan 20, 2016
Chris Wright
Jan 19, 2016
Ali Çehreli
Jan 19, 2016
Adam D. Ruppe
Mar 17, 2018
Jonathan
Mar 17, 2018
bauss
Mar 17, 2018
Ali Çehreli
January 19, 2016
I just attempted to add one ubyte to another and store the result in a ubyte but apparently ubytes get converted to ints when being added... and converting what becomes an int becomes impossible to store in a ubyte without an explicit cast...

ubyte a, b;
ubyte c = a + b; // Error: cannot implicitly convert expression (cast(int)a + cast(int)b) of type int to ubyte

On principal I'm not casting to fix this. I don't care if my computer needs to do math on a 4 byte basis, I'm not writing assembly. I'm really hoping this is a bug because trying to use any type other than ints is going to make for some really ugly code otherwise...

Can I prevent the initial implicit casts?


On the topic of complaining about casting... array lengths as ulongs is painful... any chance of an array[].lengthi being a thing?
January 19, 2016
Soviet Friend píše v Út 19. 01. 2016 v 22:12 +0000:
> I just attempted to add one ubyte to another and store the result in a ubyte but apparently ubytes get converted to ints when being added... and converting what becomes an int becomes impossible to store in a ubyte without an explicit cast...
> 
> ubyte a, b;
> ubyte c = a + b; // Error: cannot implicitly convert expression
> (cast(int)a + cast(int)b) of type int to ubyte
> 

Problem is that compiler does not know that a + b would fit in ubyte. For example if a would be 200 and b would be 100 it would not fit in ubyte. But if compiler can verify it will fit it makes cast implicit.

immutable ubyte a = 0;
ubyte b = 0;
ubyte c = a + b;

or

ubyte a = 0;
ubyte c = a + 0;

or

immutable ubyte a = 1;
immutable ubyte b = 5;
ubyte c = a + b;

works ok

but

immutable ubyte a = 1;
ubyte b = 0;
ubyte c = a + b;

can't works because b could be 255 and 255 + 1 does not fit to ubyte


> On principal I'm not casting to fix this. I don't care if my computer needs to do math on a 4 byte basis, I'm not writing assembly. I'm really hoping this is a bug because trying to use any type other than ints is going to make for some really ugly code otherwise...
> 
> Can I prevent the initial implicit casts?
> 
> 
> On the topic of complaining about casting... array lengths as ulongs is painful... any chance of an array[].lengthi being a thing?
array.length is not ulong is it size_t and I do not see any problem with that, can you be more specific.
January 19, 2016
On 01/19/2016 02:12 PM, Soviet Friend wrote:

> ubytes get converted to ints when being added...

It's a common feature involving all integral type in languages like C, C++, and D:

  https://dlang.org/spec/type.html#integer-promotions

> On the topic of complaining about casting... array lengths as ulongs is
> painful... any chance of an array[].lengthi being a thing?

That is a topic sometimes with hot debate without any resolution. Chances of it being changed in D is zero. :) Luckily, it's pretty easy in :D ;)

long lengthi(T)(T[] arr) {
    import std.exception : enforce;
    import std.conv : to;

    // No overflow here because this comparison is performed in 'ulong'
    enforce(arr.length.to!ulong < long.max);

    return arr.length.to!long;
}

unittest {
    import std.traits;
    auto arr = [ 1, 2 ];

    static assert(isSigned!(typeof(arr.lengthi)));
    assert(arr.lengthi == 2);
}


void main() {
}

Ali

January 19, 2016
On Tuesday, 19 January 2016 at 22:12:06 UTC, Soviet Friend wrote:
> I don't care if my computer needs to do math on a 4 byte basis, I'm not writing assembly.

x86 actually doesn't need to do math that way, if you were writing assembly, it would just work. This is just an annoying rule brought over by C.

> Can I prevent the initial implicit casts?

Nope, though you can help tell the compiler that you want it to fit there by doing stuff like

ubyte a = 200;
ubyte b = 100;
ubyte c = (a+b)&0xff;

or something like that, so the expression is specifically proven to fit in the byte with compile time facts.
January 20, 2016
On Tue, 19 Jan 2016 23:32:57 +0100, Daniel Kozak wrote:

> Soviet Friend píše v Út 19. 01. 2016 v 22:12 +0000:
>> I just attempted to add one ubyte to another and store the result in a ubyte but apparently ubytes get converted to ints when being added... and converting what becomes an int becomes impossible to store in a ubyte without an explicit cast...
>> 
>> ubyte a, b;
>> ubyte c = a + b; // Error: cannot implicitly convert expression
>> (cast(int)a + cast(int)b) of type int to ubyte
>> 
>> 
> Problem is that compiler does not know that a + b would fit in ubyte. For example if a would be 200 and b would be 100 it would not fit in ubyte. But if compiler can verify it will fit it makes cast implicit.

This is true for all integer types. The reason this isn't in effect for other types is that most values are small (eg array lengths), and most integer types can hold the sum of two small values. But there are plenty of small values where a [u]byte can't hold their sum.
March 17, 2018
On Tuesday, 19 January 2016 at 23:36:14 UTC, Adam D. Ruppe wrote:
> On Tuesday, 19 January 2016 at 22:12:06 UTC, Soviet Friend wrote:
>> I don't care if my computer needs to do math on a 4 byte basis, I'm not writing assembly.
>
> x86 actually doesn't need to do math that way, if you were writing assembly, it would just work. This is just an annoying rule brought over by C.
>
>> Can I prevent the initial implicit casts?
>
> Nope, though you can help tell the compiler that you want it to fit there by doing stuff like
>
> ubyte a = 200;
> ubyte b = 100;
> ubyte c = (a+b)&0xff;
>
> or something like that, so the expression is specifically proven to fit in the byte with compile time facts.


`(a+b)&0xff` What is this syntax?!  Could you give a link to this in the D documentation?  I am not even sure how to look it up...
March 17, 2018
On Saturday, 17 March 2018 at 18:36:35 UTC, Jonathan wrote:
> On Tuesday, 19 January 2016 at 23:36:14 UTC, Adam D. Ruppe wrote:
>> On Tuesday, 19 January 2016 at 22:12:06 UTC, Soviet Friend wrote:
>>> I don't care if my computer needs to do math on a 4 byte basis, I'm not writing assembly.
>>
>> x86 actually doesn't need to do math that way, if you were writing assembly, it would just work. This is just an annoying rule brought over by C.
>>
>>> Can I prevent the initial implicit casts?
>>
>> Nope, though you can help tell the compiler that you want it to fit there by doing stuff like
>>
>> ubyte a = 200;
>> ubyte b = 100;
>> ubyte c = (a+b)&0xff;
>>
>> or something like that, so the expression is specifically proven to fit in the byte with compile time facts.
>
>
> `(a+b)&0xff` What is this syntax?!  Could you give a link to this in the D documentation?  I am not even sure how to look it up...
& is the normal binary and operation, same in C, C++, Java, ...
0xFF is a hexadecimal constant (255), which the compiler knows fit in an ubyte
So what do you not understand about this syntax?
March 17, 2018
On Saturday, 17 March 2018 at 18:56:55 UTC, Dominikus Dittes Scherkl wrote:
> On Saturday, 17 March 2018 at 18:36:35 UTC, Jonathan wrote:
>> On Tuesday, 19 January 2016 at 23:36:14 UTC, Adam D. Ruppe wrote:
>>> On Tuesday, 19 January 2016 at 22:12:06 UTC, Soviet Friend wrote:
>>>> I don't care if my computer needs to do math on a 4 byte basis, I'm not writing assembly.
>>>
>>> x86 actually doesn't need to do math that way, if you were writing assembly, it would just work. This is just an annoying rule brought over by C.
>>>
>>>> Can I prevent the initial implicit casts?
>>>
>>> Nope, though you can help tell the compiler that you want it to fit there by doing stuff like
>>>
>>> ubyte a = 200;
>>> ubyte b = 100;
>>> ubyte c = (a+b)&0xff;
>>>
>>> or something like that, so the expression is specifically proven to fit in the byte with compile time facts.
>>
>>
>> `(a+b)&0xff` What is this syntax?!  Could you give a link to this in the D documentation?  I am not even sure how to look it up...
> & is the normal binary and operation, same in C, C++, Java, ...
> 0xFF is a hexadecimal constant (255), which the compiler knows fit in an ubyte
> So what do you not understand about this syntax?

I guess he doesn't understand bitwise operations.

Also don't you mean bitwise and?
March 17, 2018
On 03/17/2018 11:36 AM, Jonathan wrote:

> `(a+b)&0xff` What is this syntax?!  Could you give a link to this in the D documentation?

Here is my description of bitwise AND:


http://ddili.org/ders/d.en/bit_operations.html#ix_bit_operations.&,%20bitwise%20and

The section titled "Masking" on the same page explains what &0xff part means.

> I am not even sure how to look it up...

I hope my index section is useful in such cases. Just search for the & character there:

  http://ddili.org/ders/d.en/ix.html

Yes, there are many meanings of the & character but I think it's still useful. :)

Ali