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
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
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
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
prev sibling parent 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