www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Can't add ubytes together to make a ubyte... bug or feature?

reply Soviet Friend <dfsdfsd fdsd.com> writes:
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?
Jan 19 2016
next sibling parent reply Daniel Kozak <kozzi dlang.cz> writes:
Soviet Friend p=C3=AD=C5=A1e v =C3=9At 19. 01. 2016 v 22:12 +0000:
 I just attempted to add one ubyte to another and store the result=C2=A0
 in a ubyte but apparently ubytes get converted to ints when being=C2=A0
 added... and converting what becomes an int becomes impossible to=C2=A0
 store in a ubyte without an explicit cast...
=20
 ubyte a, b;
 ubyte c =3D a + b; // Error: cannot implicitly convert expression=C2=A0
 (cast(int)a + cast(int)b) of type int to ubyte
=20
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 =3D 0; ubyte b =3D 0; ubyte c =3D a + b; or ubyte a =3D 0; ubyte c =3D a + 0; or immutable ubyte a =3D 1; immutable ubyte b =3D 5; ubyte c =3D a + b; works ok but immutable ubyte a =3D 1; ubyte b =3D 0; ubyte c =3D 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=C2=A0
 computer needs to do math on a 4 byte basis, I'm not writing=C2=A0
 assembly. I'm really hoping this is a bug because trying to use=C2=A0
 any type other than ints is going to make for some really ugly=C2=A0
 code otherwise...
=20
 Can I prevent the initial implicit casts?
=20
=20
 On the topic of complaining about casting... array lengths as=C2=A0
 ulongs is painful... any chance of an array[].lengthi being a=C2=A0
 thing?
array.length is not ulong is it size_t and I do not see any problem with that, can you be more specific.
Jan 19 2016
parent Chris Wright <dhasenan gmail.com> writes:
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.
Jan 19 2016
prev sibling next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
Jan 19 2016
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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.
Jan 19 2016
parent reply Jonathan <JonathanILevi gmail.com> writes:
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...
Mar 17 2018
next sibling parent reply Dominikus Dittes Scherkl <dominikus scherkl.de> writes:
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?
Mar 17 2018
parent bauss <jj_1337 live.dk> writes:
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?
Mar 17 2018
prev sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
Mar 17 2018