www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - help cast

reply sdvcn <sdvcn 126.com> writes:
	dchar v11=dchar.max;
	auto vp11 = [v11];
	
	auto v2 = cast(ubyte[]) (vp11);   //v2.length=4
	auto v22 = cast(ubyte[])( [v11]); //v2.length=1


y22.length <> v2.length
Mar 18 2018
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 3/18/18 4:34 AM, sdvcn wrote:
 dchar v11=dchar.max;
      auto vp11 = [v11];
 
      auto v2 = cast(ubyte[]) (vp11);   //v2.length=4
      auto v22 = cast(ubyte[])( [v11]); //v2.length=1
This seems like a bug to me. It appears that v22 has truncated v11 to a byte and made only a single byte array out of it. -Steve
Mar 18 2018
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, March 18, 2018 13:10:28 Steven Schveighoffer via Digitalmars-d 
wrote:
 On 3/18/18 4:34 AM, sdvcn wrote:
 dchar v11=dchar.max;

      auto vp11 = [v11];

      auto v2 = cast(ubyte[]) (vp11);   //v2.length=4
      auto v22 = cast(ubyte[])( [v11]); //v2.length=1
This seems like a bug to me. It appears that v22 has truncated v11 to a byte and made only a single byte array out of it.
Except that that's precisely how you usually get an array any integral type smaller than an integer. e.g. auto arr = cast(ubyte[])([1, 2, 3, 4]); In this case, you could do ubyte[] arr = [1, 2, 3, 4]; instead, but if you're not dealing with an initializaton or assignment like this (e.g. you're passing the array to a functon), then the cast is the way you do it. Normally, you do it with integer literals, and I could see an argument that it shouldn't allow it without VRP being used to make it work, but it _is_ a cast, and casts are a bit of a blunt instrument. So, I really don't think that it's a bug. - Jonathan M Davis
Mar 18 2018
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 3/18/18 2:24 PM, Jonathan M Davis wrote:
 On Sunday, March 18, 2018 13:10:28 Steven Schveighoffer via Digitalmars-d
 wrote:
 On 3/18/18 4:34 AM, sdvcn wrote:
 dchar v11=dchar.max;

       auto vp11 = [v11];

       auto v2 = cast(ubyte[]) (vp11);   //v2.length=4
       auto v22 = cast(ubyte[])( [v11]); //v2.length=1
This seems like a bug to me. It appears that v22 has truncated v11 to a byte and made only a single byte array out of it.
Except that that's precisely how you usually get an array any integral type smaller than an integer. e.g. auto arr = cast(ubyte[])([1, 2, 3, 4]); In this case, you could do ubyte[] arr = [1, 2, 3, 4]; instead, but if you're not dealing with an initializaton or assignment like this (e.g. you're passing the array to a functon), then the cast is the way you do it. Normally, you do it with integer literals, and I could see an argument that it shouldn't allow it without VRP being used to make it work, but it _is_ a cast, and casts are a bit of a blunt instrument. So, I really don't think that it's a bug.
It's quite possible that you aren't understanding what is happening: ubyte[] arr = cast(ubyte[])[555]; writeln(arr); // [43] Why is this not a bug? I didn't cast the 555 to a ubyte, so it should either complain that it can't do it, or give me an array of 4 bytes. I guess it could be explained as the same thing as: ubyte[] arr = [cast(ubyte)555]; But this is surprisingly weird behavior. -Steve
Mar 18 2018
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, March 18, 2018 14:56:04 Steven Schveighoffer via Digitalmars-d 
wrote:
 On 3/18/18 2:24 PM, Jonathan M Davis wrote:
 On Sunday, March 18, 2018 13:10:28 Steven Schveighoffer via
 Digitalmars-d

 wrote:
 On 3/18/18 4:34 AM, sdvcn wrote:
 dchar v11=dchar.max;

       auto vp11 = [v11];

       auto v2 = cast(ubyte[]) (vp11);   //v2.length=4
       auto v22 = cast(ubyte[])( [v11]); //v2.length=1
This seems like a bug to me. It appears that v22 has truncated v11 to a byte and made only a single byte array out of it.
Except that that's precisely how you usually get an array any integral type smaller than an integer. e.g. auto arr = cast(ubyte[])([1, 2, 3, 4]); In this case, you could do ubyte[] arr = [1, 2, 3, 4]; instead, but if you're not dealing with an initializaton or assignment like this (e.g. you're passing the array to a functon), then the cast is the way you do it. Normally, you do it with integer literals, and I could see an argument that it shouldn't allow it without VRP being used to make it work, but it _is_ a cast, and casts are a bit of a blunt instrument. So, I really don't think that it's a bug.
It's quite possible that you aren't understanding what is happening: ubyte[] arr = cast(ubyte[])[555]; writeln(arr); // [43] Why is this not a bug? I didn't cast the 555 to a ubyte, so it should either complain that it can't do it, or give me an array of 4 bytes. I guess it could be explained as the same thing as: ubyte[] arr = [cast(ubyte)555]; But this is surprisingly weird behavior.
That's exactly what it's doing, and when you have multiple elements in the literal, it quickly gets a lot more pleasant than casting each element individually. e.g. cast(ubyte[])[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] vs [cast(ubyte)0, cast(ubyte)1, cast(ubyte)2, cast(ubyte)3, cast(ubyte)4, cast(ubyte)5, cast(ubyte)6, cast(ubyte)7, cast(ubyte)8, cast(ubyte)9, cast(ubyte)10] I use this trick all the time when creating arrays of integral types smaller than int, precisely because casting each element is a royal pain and way harder to read. - Jonathan M Davis
Mar 18 2018
next sibling parent sdvcn <sdvcn 126.com> writes:
On Sunday, 18 March 2018 at 20:07:28 UTC, Jonathan M Davis wrote:
 On Sunday, March 18, 2018 14:56:04 Steven Schveighoffer via 
 Digitalmars-d wrote:
 On 3/18/18 2:24 PM, Jonathan M Davis wrote:
 On Sunday, March 18, 2018 13:10:28 Steven Schveighoffer via 
 Digitalmars-d

 wrote:
 On 3/18/18 4:34 AM, sdvcn wrote:
 dchar v11=dchar.max;

       auto vp11 = [v11];

       auto v2 = cast(ubyte[]) (vp11);   //v2.length=4
       auto v22 = cast(ubyte[])( [v11]); //v2.length=1
This seems like a bug to me. It appears that v22 has truncated v11 to a byte and made only a single byte array out of it.
Except that that's precisely how you usually get an array any integral type smaller than an integer. e.g. auto arr = cast(ubyte[])([1, 2, 3, 4]); In this case, you could do ubyte[] arr = [1, 2, 3, 4]; instead, but if you're not dealing with an initializaton or assignment like this (e.g. you're passing the array to a functon), then the cast is the way you do it. Normally, you do it with integer literals, and I could see an argument that it shouldn't allow it without VRP being used to make it work, but it _is_ a cast, and casts are a bit of a blunt instrument. So, I really don't think that it's a bug.
It's quite possible that you aren't understanding what is happening: ubyte[] arr = cast(ubyte[])[555]; writeln(arr); // [43] Why is this not a bug? I didn't cast the 555 to a ubyte, so it should either complain that it can't do it, or give me an array of 4 bytes. I guess it could be explained as the same thing as: ubyte[] arr = [cast(ubyte)555]; But this is surprisingly weird behavior.
That's exactly what it's doing, and when you have multiple elements in the literal, it quickly gets a lot more pleasant than casting each element individually. e.g. cast(ubyte[])[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] vs [cast(ubyte)0, cast(ubyte)1, cast(ubyte)2, cast(ubyte)3, cast(ubyte)4, cast(ubyte)5, cast(ubyte)6, cast(ubyte)7, cast(ubyte)8, cast(ubyte)9, cast(ubyte)10] I use this trick all the time when creating arrays of integral types smaller than int, precisely because casting each element is a royal pain and way harder to read. - Jonathan M Davis
代码目的是转换任意类行到ubyte[] The object of the code is to convert any class of rows to ubyte[] 但是非数组类无法正确转化 But non - array classes can't be converted correctly void pByte(T)(T v) { ubyte[] uBuf; static if(isArray!T){ uBuf = cast(ubyte[])mKey; }else{ uBuf = cast(ubyte[])[v]; } writeln(uBuf); } 无法得到正确结果 Unable to get the correct result
Mar 18 2018
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 3/18/18 4:07 PM, Jonathan M Davis wrote:

 That's exactly what it's doing, and when you have multiple elements in the
 literal, it quickly gets a lot more pleasant than casting each element
 individually. e.g.
 
 cast(ubyte[])[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 
 vs
 
 [cast(ubyte)0, cast(ubyte)1, cast(ubyte)2, cast(ubyte)3, cast(ubyte)4,
   cast(ubyte)5, cast(ubyte)6, cast(ubyte)7, cast(ubyte)8, cast(ubyte)9,
   cast(ubyte)10]
 
 I use this trick all the time when creating arrays of integral types smaller
 than int, precisely because casting each element is a royal pain and way
 harder to read.
Let me adjust your example a bit, and see if you still agree: auto bytes = cast(ubyte[])[55_444, 289, 1_000_000, 846, 123_456_789]; writeln(bytes); // [148, 33, 64, 78, 21] I have used cast(ubyte[]) to get ubytes as well, but I normally would do this for values that actually *could be* ubytes. for values higher than ubytes, I would not have expected implicit truncation. It's especially confusing to someone who has seen when you cast an int[] to a ubyte[], and gets the bytes for that same data. When I use cast(ubyte[]), I took it to mean "pretend this is a ubyte[] literal", not "cast each element to ubyte". I can also see this biting someone who has a long set of ubytes, and accidentally does one that is larger than 255. -Steve
Mar 19 2018
next sibling parent bauss <jj_1337 live.dk> writes:
On Monday, 19 March 2018 at 11:20:05 UTC, Steven Schveighoffer 
wrote:
 On 3/18/18 4:07 PM, Jonathan M Davis wrote:

 That's exactly what it's doing, and when you have multiple 
 elements in the
 literal, it quickly gets a lot more pleasant than casting each 
 element
 individually. e.g.
 
 cast(ubyte[])[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 
 vs
 
 [cast(ubyte)0, cast(ubyte)1, cast(ubyte)2, cast(ubyte)3, 
 cast(ubyte)4,
   cast(ubyte)5, cast(ubyte)6, cast(ubyte)7, cast(ubyte)8, 
 cast(ubyte)9,
   cast(ubyte)10]
 
 I use this trick all the time when creating arrays of integral 
 types smaller
 than int, precisely because casting each element is a royal 
 pain and way
 harder to read.
Let me adjust your example a bit, and see if you still agree: auto bytes = cast(ubyte[])[55_444, 289, 1_000_000, 846, 123_456_789]; writeln(bytes); // [148, 33, 64, 78, 21] I have used cast(ubyte[]) to get ubytes as well, but I normally would do this for values that actually *could be* ubytes. for values higher than ubytes, I would not have expected implicit truncation. It's especially confusing to someone who has seen when you cast an int[] to a ubyte[], and gets the bytes for that same data. When I use cast(ubyte[]), I took it to mean "pretend this is a ubyte[] literal", not "cast each element to ubyte". I can also see this biting someone who has a long set of ubytes, and accidentally does one that is larger than 255. -Steve
An even funnier example. auto bytes = cast(ubyte[])cast(int[])[55_444, 289, 1_000_000, 846, 123_456_789]; auto bytes2 = cast(int[])[55_444, 289, 1_000_000, 846, 123_456_789]; auto bytes3 = cast(ubyte[])bytes2; writeln(bytes); // Guess what the output is here. writeln(bytes2); // Prints:[55444, 289, 1000000, 846, 123456789] writeln(bytes3); // Prints: [148, 216, 0, 0, 33, 1, 0, 0, 64, 66, 15, 0, 78, 3, 0, 0, 21, 205, 91, 7]
Mar 19 2018
prev sibling parent John Colvin <john.loughran.colvin gmail.com> writes:
On Monday, 19 March 2018 at 11:20:05 UTC, Steven Schveighoffer 
wrote:
 Let me adjust your example a bit, and see if you still agree:

 auto bytes = cast(ubyte[])[55_444, 289, 1_000_000, 846, 
 123_456_789];

 writeln(bytes); // [148, 33, 64, 78, 21]

 I have used cast(ubyte[]) to get ubytes as well, but I normally 
 would do this for values that actually *could be* ubytes. for 
 values higher than ubytes, I would not have expected implicit 
 truncation. It's especially confusing to someone who has seen 
 when you cast an int[] to a ubyte[], and gets the bytes for 
 that same data. When I use cast(ubyte[]), I took it to mean 
 "pretend this is a ubyte[] literal", not "cast each element to 
 ubyte".

 I can also see this biting someone who has a long set of 
 ubytes, and accidentally does one that is larger than 255.

 -Steve
Raw `cast` is just nasty. It's overloaded and confusing. Wrapper template functions like `reinterpretBitsAs` can help alleviate the pain, e.g. `assert([1, 2, 3].reinterpretBitsAs!(ubyte[]).length == 12);`. I feel like C++ got it right (or just less wrong) with casts.
Mar 19 2018