digitalmars.D - Not sure
- Tom (13/13) Dec 14 2005 I'm not sure if someone post this before (maybe this is just a copy-past...
- Regan Heath (11/25) Dec 14 2005 Try:
- Tom (3/30) Dec 14 2005 Yap, this works fine but, why is the former bad?
- Regan Heath (18/51) Dec 14 2005 Tough question :)
- James Dunne (31/98) Dec 14 2005 No, it's a bad idea for the D language spec to assume any
- Regan Heath (25/71) Dec 15 2005 ub is not a dynamic array it is a static array. That said (I believe) yo...
- James Dunne (12/112) Dec 15 2005 Oops again. :)
- Regan Heath (14/63) Dec 15 2005 You're missing my point. Answer me this; the cast is illegal because
- Derek Parnell (15/16) Dec 15 2005 On Thu, 15 Dec 2005 13:56:13 -0600, James Dunne wrote:
- Tom (7/23) Dec 15 2005 Again people :D, I appreciate the workarounds very much but as I said be...
- Derek Parnell (9/10) Dec 14 2005 Oh... you just wanted to copy the integer to the ub array. Okay.
- Regan Heath (7/10) Dec 15 2005 The alternative to copying is to use a dynamic array instead of a static...
- Derek Parnell (45/58) Dec 14 2005 I'm not sure what you are attempting to do. But if you are trying to hav...
- Bruno Medeiros (11/19) Dec 16 2005 Whoa, now that is strange. I've allways thought that the dynamic
- Tom (7/21) Dec 16 2005 I don't think it's more natural but I agree that casting would be
- Sean Kelly (7/24) Dec 16 2005 Switching them would break the ability to do this:
- Bruno Medeiros (12/40) Dec 17 2005 Do we care? :p On the other hand switching would allow this:
- James Dunne (4/44) Dec 18 2005 Don't forget about UTF-8... Using writef is a better alternative
- Oskar Linde (4/7) Dec 19 2005 Except for throwing on bad code units/combinations, In what way does
- MicroWizard (7/20) Dec 15 2005 I think you just wanted to convert a 32 bit int to it's binary
- Tom (5/28) Dec 15 2005 Oh, yes, int = 32bits it's guaranteed as D defines so in it's specs. Wit...
- Derek Parnell (16/29) Dec 15 2005 Oops, I got side tracked ;-)
- Regan Heath (9/34) Dec 15 2005 I don't think "not stored in RAM" is the reason, consider:
- Derek Parnell (14/55) Dec 15 2005 True ... I think D has made a big mistake in using a single keyword 'cas...
- Regan Heath (13/67) Dec 15 2005 I'm not sure you can ever paint something as a static array because you ...
- Derek Parnell (33/45) Dec 15 2005 A fixed-size array (a.k.a static array) does not have a data pointer. It
- Regan Heath (6/14) Dec 15 2005 I realise that. A fixed sized array _is_ just a data pointer and that
- Derek Parnell (42/58) Dec 15 2005 Sorry about this, but my point is that a fixed size array _is_not_ a dat...
- Bruno Medeiros (29/46) Dec 16 2005 I think you are both /sorta/ wrong.
- Oskar Linde (27/50) Dec 19 2005 Upon declaration, a static array defines the storage of its contents,
I'm not sure if someone post this before (maybe this is just a copy-paste, I don't recall as I have the d file missed in some directory and I've just found it), but I'm wondering isn't this cast possible? test.d(5): cannot cast int* to ubyte[4] DMD 0.141 Tom
Dec 14 2005
On Thu, 15 Dec 2005 01:58:59 +0000 (UTC), Tom <Tom_member pathlink.com> wrote:I'm not sure if someone post this before (maybe this is just a copy-paste, I don't recall as I have the d file missed in some directory and I've just found it), but I'm wondering isn't this cast possible? test.d(5): cannot cast int* to ubyte[4] DMD 0.141Try: Regan
Dec 14 2005
In article <ops1sym6qr23k2f5 nrage.netwin.co.nz>, Regan Heath says...On Thu, 15 Dec 2005 01:58:59 +0000 (UTC), Tom <Tom_member pathlink.com> wrote:Yap, this works fine but, why is the former bad? TomI'm not sure if someone post this before (maybe this is just a copy-paste, I don't recall as I have the d file missed in some directory and I've just found it), but I'm wondering isn't this cast possible? test.d(5): cannot cast int* to ubyte[4] DMD 0.141Try: Regan
Dec 14 2005
On Thu, 15 Dec 2005 02:33:02 +0000 (UTC), Tom <Tom_member pathlink.com> wrote:In article <ops1sym6qr23k2f5 nrage.netwin.co.nz>, Regan Heath says...Tough question :) ubyte[4] is a static array. I believe D implements it as a pointer to a block of memory, and does macro style replacement of "ub.length" with "4". &i is an int*, a pointer to a block of memory containing an 'int' (supposedly). Both blocks of memory are 4 bytes long. So, apart from one technically supposedly being an "int" and the other technically being "4 bytes in a row" they're the same thing. However, I do not think it's possible to make a static array point to another address, so this may be why it fails. My code works because you can slice a pointer/memory address to create a dynamic array of the type of the pointer. The statement: (cast(ubyte*)&i)[0..4]; creates a temporary dynamic array, which is then copied into the memory block pointed to by ub, the static array. ReganOn Thu, 15 Dec 2005 01:58:59 +0000 (UTC), Tom <Tom_member pathlink.com> wrote:Yap, this works fine but, why is the former bad?I'm not sure if someone post this before (maybe this is just a copy-paste, I don't recall as I have the d file missed in some directory and I've just found it), but I'm wondering isn't this cast possible? test.d(5): cannot cast int* to ubyte[4] DMD 0.141Try: Regan
Dec 14 2005
Regan Heath wrote:On Thu, 15 Dec 2005 02:33:02 +0000 (UTC), Tom <Tom_member pathlink.com> wrote:No, it's a bad idea for the D language spec to assume any implementation-specific details. In this case, the implementation of a dynamic array. At no point in the D language spec regarding dynamic arrays is any ordering of the fields in the implicit memory structure of a dynamic array stated. In fact, Walter points out that relying on such implementation-specific details to get printf working is a bad idea: "In the future, it may be necessary to just add a new format specifier to printf() instead of relying on an implementation dependent detail." (from http://digitalmars.com/d/arrays.html under 'printf() and Strings' section). What he is referring to is that strings are special-case dynamic arrays. The printf '%.*s' format specifier expects a length integer followed by a data pointer. It just so happens to be (most likely by design) that the reference DMD compiler orders the dynamic array's fields in memory as length first, followed by data pointer. Thus, your argument shouldn't hold in general because you're assuming the D language defines the ordering of the dynamic array's members.In article <ops1sym6qr23k2f5 nrage.netwin.co.nz>, Regan Heath says...Tough question :) ubyte[4] is a static array. I believe D implements it as a pointer to a block of memory, and does macro style replacement of "ub.length" with "4". &i is an int*, a pointer to a block of memory containing an 'int' (supposedly). Both blocks of memory are 4 bytes long. So, apart from one technically supposedly being an "int" and the other technically being "4 bytes in a row" they're the same thing.On Thu, 15 Dec 2005 01:58:59 +0000 (UTC), Tom <Tom_member pathlink.com> wrote:Yap, this works fine but, why is the former bad?I'm not sure if someone post this before (maybe this is just a copy-paste, I don't recall as I have the d file missed in some directory and I've just found it), but I'm wondering isn't this cast possible? test.d(5): cannot cast int* to ubyte[4] DMD 0.141Try: ReganHowever, I do not think it's possible to make a static array point to another address, so this may be why it fails.No, the compiler states quite clearly that the cast from an int* to a ubyte[4] is simply not allowed. I'm not disagreeing that you cannot modify the address a static array points to, I'm just disagreeing with your proposed reason for the 'failure' case. I believe for a cast from a pointer to an array to succeed, both element types must be exactly equivalent, not just source pointer-element type castable to destination array-element type.My code works because you can slice a pointer/memory address to create a dynamic array of the type of the pointer. The statement: (cast(ubyte*)&i)[0..4]; creates a temporary dynamic array, which is then copied into the memory block pointed to by ub, the static array.I don't believe this creates any memory. Slices are references to the original data. What effectively is being done here is copying 4 ubytes from the address of a local int variable into the ub[] static array. If one does not want the value copied, then simply use a union on int and ubyte[4].Regan
Dec 14 2005
On Thu, 15 Dec 2005 00:31:18 -0600, James Dunne <james.jdunne gmail.com> wrote:Regan Heath wrote:ub is not a dynamic array it is a static array. That said (I believe) you point is still valid because I can't recall reading anything defining the static array implementation either (what I know of it is based on observation and guess work)On Thu, 15 Dec 2005 02:33:02 +0000 (UTC), Tom <Tom_member pathlink.com> wrote:No, it's a bad idea for the D language spec to assume any implementation-specific details. In this case, the implementation of a dynamic array.In article <ops1sym6qr23k2f5 nrage.netwin.co.nz>, Regan Heath says...Both blocks of memory are 4 bytes long. So, apart from one technically supposedly being an "int" and the other technically being "4 bytes in a row" they're the same thing.At no point in the D language spec regarding dynamic arrays is any ordering of the fields in the implicit memory structure of a dynamic array stated. In fact, Walter points out that relying on such implementation-specific details to get printf working is a bad idea: "In the future, it may be necessary to just add a new format specifier to printf() instead of relying on an implementation dependent detail." (from http://digitalmars.com/d/arrays.html under 'printf() and Strings' section). What he is referring to is that strings are special-case dynamic arrays. The printf '%.*s' format specifier expects a length integer followed by a data pointer. It just so happens to be (most likely by design) that the reference DMD compiler orders the dynamic array's fields in memory as length first, followed by data pointer. Thus, your argument shouldn't hold in general because you're assuming the D language defines the ordering of the dynamic array's members.You make a valid point, for dynamic arrays.. but we're not talking about dynamic arrays :)There must be some reason the compiler is disallowing it, it's not doing so just out of spite, right? As to what that reason is.. my best guess remains that a static array pointer is immutable. (which happens to be the implementation that was chosen by DMD, and is undefined in the spec to my knowledge)However, I do not think it's possible to make a static array point to another address, so this may be why it fails.No, the compiler states quite clearly that the cast from an int* to a ubyte[4] is simply not allowed. I'm not disagreeing that you cannot modify the address a static array points to, I'm just disagreeing with your proposed reason for the 'failure' case.I believe for a cast from a pointer to an array to succeed, both element types must be exactly equivalent, not just source pointer-element type castable to destination array-element type.AFAIK you can't actually cast from a pointer to an array. Unless you count what Derek posted: *(cast(int**)(cast(void*)&ub + int.sizeof)) = &i; You can however slice a pointer which creates a dynamic array, that's what happens here: (cast(ubyte*)&i)[0..4];Correct, except when you slice a pointer you get a dynamic array, a dynamic array consists of a pointer and a length, or 8 bytes of data, so, unless the compiler optimises this away this statement: ub[] = (cast(ubyte*)&i)[0..4]; uses 8 bytes of temporary memory on the stack (or is it on the heap?) ReganMy code works because you can slice a pointer/memory address to create a dynamic array of the type of the pointer. The statement: (cast(ubyte*)&i)[0..4]; creates a temporary dynamic array, which is then copied into the memory block pointed to by ub, the static array.I don't believe this creates any memory. Slices are references to the original data. What effectively is being done here is copying 4 ubytes from the address of a local int variable into the ub[] static array.
Dec 15 2005
Regan Heath wrote:On Thu, 15 Dec 2005 00:31:18 -0600, James Dunne <james.jdunne gmail.com> wrote:Oops on the dynamic array stuff.Regan Heath wrote:ub is not a dynamic array it is a static array. That said (I believe) you point is still valid because I can't recall reading anything defining the static array implementation either (what I know of it is based on observation and guess work)On Thu, 15 Dec 2005 02:33:02 +0000 (UTC), Tom <Tom_member pathlink.com> wrote:No, it's a bad idea for the D language spec to assume any implementation-specific details. In this case, the implementation of a dynamic array.In article <ops1sym6qr23k2f5 nrage.netwin.co.nz>, Regan Heath says...Both blocks of memory are 4 bytes long. So, apart from one technically supposedly being an "int" and the other technically being "4 bytes in a row" they're the same thing.Oops again. :)At no point in the D language spec regarding dynamic arrays is any ordering of the fields in the implicit memory structure of a dynamic array stated. In fact, Walter points out that relying on such implementation-specific details to get printf working is a bad idea: "In the future, it may be necessary to just add a new format specifier to printf() instead of relying on an implementation dependent detail." (from http://digitalmars.com/d/arrays.html under 'printf() and Strings' section). What he is referring to is that strings are special-case dynamic arrays. The printf '%.*s' format specifier expects a length integer followed by a data pointer. It just so happens to be (most likely by design) that the reference DMD compiler orders the dynamic array's fields in memory as length first, followed by data pointer. Thus, your argument shouldn't hold in general because you're assuming the D language defines the ordering of the dynamic array's members.You make a valid point, for dynamic arrays.. but we're not talking about dynamic arrays :)No, the original code posted is not modifying the static array's effective pointer, but is instead attempting to copy the data out of a casted-to ubyte[4] static array. The cast is what is the invalid operation here.There must be some reason the compiler is disallowing it, it's not doing so just out of spite, right? As to what that reason is.. my best guess remains that a static array pointer is immutable. (which happens to be the implementation that was chosen by DMD, and is undefined in the spec to my knowledge)However, I do not think it's possible to make a static array point to another address, so this may be why it fails.No, the compiler states quite clearly that the cast from an int* to a ubyte[4] is simply not allowed. I'm not disagreeing that you cannot modify the address a static array points to, I'm just disagreeing with your proposed reason for the 'failure' case.I believe the implementation of the slice call is defined in the phobos standard library as a regular C function call, so it is not up to the language to decide what to do here. The memory should be allocated dynamically on the heap, but it is definitely not required to be. This is another implementation detail.I believe for a cast from a pointer to an array to succeed, both element types must be exactly equivalent, not just source pointer-element type castable to destination array-element type.AFAIK you can't actually cast from a pointer to an array. Unless you count what Derek posted: *(cast(int**)(cast(void*)&ub + int.sizeof)) = &i; You can however slice a pointer which creates a dynamic array, that's what happens here: (cast(ubyte*)&i)[0..4];Correct, except when you slice a pointer you get a dynamic array, a dynamic array consists of a pointer and a length, or 8 bytes of data, so, unless the compiler optimises this away this statement: ub[] = (cast(ubyte*)&i)[0..4]; uses 8 bytes of temporary memory on the stack (or is it on the heap?) ReganMy code works because you can slice a pointer/memory address to create a dynamic array of the type of the pointer. The statement: (cast(ubyte*)&i)[0..4]; creates a temporary dynamic array, which is then copied into the memory block pointed to by ub, the static array.I don't believe this creates any memory. Slices are references to the original data. What effectively is being done here is copying 4 ubytes from the address of a local int variable into the ub[] static array.
Dec 15 2005
On Thu, 15 Dec 2005 13:56:13 -0600, James Dunne <james.jdunne gmail.com> wrote:You're missing my point. Answer me this; the cast is illegal because _______? You're correct, the original code was not modifying the pointer, my mistake. But, there must be some reason the cast is illegal. That reason appears to me to be that there is simply no such thing as a temporary static array, perhaps due to the nature/specification of them, perhaps due to the implementation of them, perhaps some other reason...No, the original code posted is not modifying the static array's effective pointer, but is instead attempting to copy the data out of a casted-to ubyte[4] static array. The cast is what is the invalid operation here.There must be some reason the compiler is disallowing it, it's not doing so just out of spite, right? As to what that reason is.. my best guess remains that a static array pointer is immutable. (which happens to be the implementation that was chosen by DMD, and is undefined in the spec to my knowledge)However, I do not think it's possible to make a static array point to another address, so this may be why it fails.No, the compiler states quite clearly that the cast from an int* to a ubyte[4] is simply not allowed. I'm not disagreeing that you cannot modify the address a static array points to, I'm just disagreeing with your proposed reason for the 'failure' case.Sure, it's entirely possible a clever implementation can optimise the temporary away. Regardless it's important to understand what is going on figuratively if not actually, as the first usually leads to the other. ReganI believe the implementation of the slice call is defined in the phobos standard library as a regular C function call, so it is not up to the language to decide what to do here. The memory should be allocated dynamically on the heap, but it is definitely not required to be. This is another implementation detail.I believe for a cast from a pointer to an array to succeed, both element types must be exactly equivalent, not just source pointer-element type castable to destination array-element type.AFAIK you can't actually cast from a pointer to an array. Unless you count what Derek posted: *(cast(int**)(cast(void*)&ub + int.sizeof)) = &i; You can however slice a pointer which creates a dynamic array, that's what happens here: (cast(ubyte*)&i)[0..4];Correct, except when you slice a pointer you get a dynamic array, a dynamic array consists of a pointer and a length, or 8 bytes of data, so, unless the compiler optimises this away this statement: ub[] = (cast(ubyte*)&i)[0..4]; uses 8 bytes of temporary memory on the stack (or is it on the heap?) ReganMy code works because you can slice a pointer/memory address to create a dynamic array of the type of the pointer. The statement: (cast(ubyte*)&i)[0..4]; creates a temporary dynamic array, which is then copied into the memory block pointed to by ub, the static array.I don't believe this creates any memory. Slices are references to the original data. What effectively is being done here is copying 4 ubytes from the address of a local int variable into the ub[] static array.
Dec 15 2005
On Thu, 15 Dec 2005 13:56:13 -0600, James Dunne wrote: BTW, the D Language docs in the ABI section clearly defines the dynamic array implementation structure. -------------- Arrays A dynamic array consists of: offset contents 0 array dimension 4 pointer to array data ------------------- So this code is 'legal' but still hackish.-- Derek Parnell Melbourne, Australia 16/12/2005 7:51:40 AM*(cast(int**)(cast(void*)&ub + int.sizeof)) = &i;
Dec 15 2005
Again people :D, I appreciate the workarounds very much but as I said before, this isn't real code excerpt but a pure abstract example. The only question I'm asking here (and I wish someone can answer) is why is the cast wrong?, as Regan (I think) understood from the very beginning. Thanks :) Tom In article <ikigr00oc3am.1aykemsuvx5on.dlg 40tude.net>, Derek Parnell says...On Thu, 15 Dec 2005 13:56:13 -0600, James Dunne wrote: BTW, the D Language docs in the ABI section clearly defines the dynamic array implementation structure. -------------- Arrays A dynamic array consists of: offset contents 0 array dimension 4 pointer to array data ------------------- So this code is 'legal' but still hackish.-- Derek Parnell Melbourne, Australia 16/12/2005 7:51:40 AM*(cast(int**)(cast(void*)&ub + int.sizeof)) = &i;
Dec 15 2005
On Thu, 15 Dec 2005 02:33:02 +0000 (UTC), Tom wrote:Oh... you just wanted to copy the integer to the ub array. Okay. -- Derek (skype: derek.j.parnell) Melbourne, Australia "A learning experience is one of those things that says, 'You know that thing you just did? Don't do that.'" - D.N. Adams 15/12/2005 6:13:01 PM
Dec 14 2005
On Thu, 15 Dec 2005 18:13:54 +1100, Derek Parnell <derek psych.ward> wrote:On Thu, 15 Dec 2005 02:33:02 +0000 (UTC), Tom wrote:The alternative to copying is to use a dynamic array instead of a static one, i.e. ubyte[] ub; and to assign rather than copy the result, i.e. ub = (cast(ubyte*)&i)[0..4] ReganOh... you just wanted to copy the integer to the ub array. Okay.
Dec 15 2005
On Thu, 15 Dec 2005 01:58:59 +0000 (UTC), Tom wrote:I'm not sure if someone post this before (maybe this is just a copy-paste, I don't recall as I have the d file missed in some directory and I've just found it), but I'm wondering isn't this cast possible? test.d(5): cannot cast int* to ubyte[4]I'm not sure what you are attempting to do. But if you are trying to have 'ub' reference the integer 'i' as if it was four bytes then this might do the trick (btw: its a hack 'cos it assumes D's dynamic array ABI is not going to change). ----------------- import std.stdio; int main( char[][] args ) { int i; ubyte[] ub; // Set the length first! ub.length = i.sizeof; // Pretend that the 2nd part of ub (the pointer part) is // a pointer to a integer rather than the RAM that // was allocated by setting the length. Set this part // to point to the integer in question. *(cast(int**)(cast(void*)&ub + int.sizeof)) = &i; i = 11; writefln("i = %d", i); writefln("ub = %s", ub); i = 222; writefln("i = %d", i); writefln("ub = %s", ub); i = 3333; writefln("i = %d", i); writefln("ub = %s", ub); return 0; } --------------------- OUTPUT::::: i = 11 ub = [11,0,0,0] i = 222 ub = [222,0,0,0] i = 3333 ub = [5,13,0,0] Personally, I'd use a union instead ;-) -- Derek (skype: derek.j.parnell) Melbourne, Australia "A learning experience is one of those things that says, 'You know that thing you just did? Don't do that.'" - D.N. Adams 15/12/2005 6:05:15 PM
Dec 14 2005
Derek Parnell wrote:On Thu, 15 Dec 2005 01:58:59 +0000 (UTC), Tom wrote: ub.length = i.sizeof; // Pretend that the 2nd part of ub (the pointer part) is // a pointer to a integer rather than the RAM that // was allocated by setting the length. Set this part // to point to the integer in question. *(cast(int**)(cast(void*)&ub + int.sizeof)) = &i;Whoa, now that is strange. I've allways thought that the dynamic arrays's first element was the pointer, and the second the length. It just seem more natural that way, because.. well, it makes them more like pointers. For instance, you could do an opaque cast of dyn array to pointer (of the same type), and also the (generated assembly) code to index a dyn array would be the same as the pointer's. -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Dec 16 2005
In article <dnv1p9$2gv0$1 digitaldaemon.com>, Bruno Medeiros says...Derek Parnell wrote:I don't think it's more natural but I agree that casting would be straightforward if that was the case (don't have to add to the pointer). Was that you were referring about making it more like a pointer? I always thought it was implemented as prefixed length as in other languages strings are. Not sure :) Tom;On Thu, 15 Dec 2005 01:58:59 +0000 (UTC), Tom wrote: ub.length = i.sizeof; // Pretend that the 2nd part of ub (the pointer part) is // a pointer to a integer rather than the RAM that // was allocated by setting the length. Set this part // to point to the integer in question. *(cast(int**)(cast(void*)&ub + int.sizeof)) = &i;Whoa, now that is strange. I've allways thought that the dynamic arrays's first element was the pointer, and the second the length. It just seem more natural that way, because.. well, it makes them more like pointers. [...]
Dec 16 2005
Bruno Medeiros wrote:Derek Parnell wrote:Switching them would break the ability to do this: char[] buf; printf( "%.*s", buf ); Also, it's typical for length information to precede the data--allocated memory blocks, for example. SeanOn Thu, 15 Dec 2005 01:58:59 +0000 (UTC), Tom wrote: ub.length = i.sizeof; // Pretend that the 2nd part of ub (the pointer part) is // a pointer to a integer rather than the RAM that // was allocated by setting the length. Set this part // to point to the integer in question. *(cast(int**)(cast(void*)&ub + int.sizeof)) = &i;> Whoa, now that is strange. I've allways thought that the dynamic arrays's first element was the pointer, and the second the length. It just seem more natural that way, because.. well, it makes them more like pointers. For instance, you could do an opaque cast of dyn array to pointer (of the same type), and also the (generated assembly) code to index a dyn array would be the same as the pointer's.
Dec 16 2005
Sean Kelly wrote:Bruno Medeiros wrote:Do we care? :p On the other hand switching would allow this: char[] buf; printf( "%s", buf ); well, mostly... if it weren't for the zero-termination issue. In fact, since the moment that printf is made to work with zero-terminated strings, and D's strings are not zero-terminated, we probably shouldn't bother with any kind of (direct) compatibility. -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."Derek Parnell wrote:Switching them would break the ability to do this: char[] buf; printf( "%.*s", buf );On Thu, 15 Dec 2005 01:58:59 +0000 (UTC), Tom wrote: ub.length = i.sizeof; // Pretend that the 2nd part of ub (the pointer part) is // a pointer to a integer rather than the RAM that // was allocated by setting the length. Set this part // to point to the integer in question. *(cast(int**)(cast(void*)&ub + int.sizeof)) = &i;> Whoa, now that is strange. I've allways thought that the dynamic arrays's first element was the pointer, and the second the length. It just seem more natural that way, because.. well, it makes them more like pointers. For instance, you could do an opaque cast of dyn array to pointer (of the same type), and also the (generated assembly) code to index a dyn array would be the same as the pointer's.
Dec 17 2005
Bruno Medeiros wrote:Sean Kelly wrote:Don't forget about UTF-8... Using writef is a better alternative anyway. I don't use it much myself since I use ASCII strings, and writef is much slower than printf.Bruno Medeiros wrote:Do we care? :p On the other hand switching would allow this: char[] buf; printf( "%s", buf ); well, mostly... if it weren't for the zero-termination issue. In fact, since the moment that printf is made to work with zero-terminated strings, and D's strings are not zero-terminated, we probably shouldn't bother with any kind of (direct) compatibility.Derek Parnell wrote:Switching them would break the ability to do this: char[] buf; printf( "%.*s", buf );On Thu, 15 Dec 2005 01:58:59 +0000 (UTC), Tom wrote: ub.length = i.sizeof; // Pretend that the 2nd part of ub (the pointer part) is // a pointer to a integer rather than the RAM that // was allocated by setting the length. Set this part // to point to the integer in question. *(cast(int**)(cast(void*)&ub + int.sizeof)) = &i;> Whoa, now that is strange. I've allways thought that the dynamic arrays's first element was the pointer, and the second the length. It just seem more natural that way, because.. well, it makes them more like pointers. For instance, you could do an opaque cast of dyn array to pointer (of the same type), and also the (generated assembly) code to index a dyn array would be the same as the pointer's.
Dec 18 2005
James Dunne wrote:Don't forget about UTF-8... Using writef is a better alternative anyway. I don't use it much myself since I use ASCII strings, and writef is much slower than printf.Except for throwing on bad code units/combinations, In what way does writef handle UTF-8 that printf doesn't? /Oskar
Dec 19 2005
I think you just wanted to convert a 32 bit int to it's binary representative. However the mentioned cast should be work somehow, you have to use union for this problem keeping in mind that the result depends on the underlying architecture eg. big or little endianness. On the other hand 'int' is 32 bit now but it is not guaranteed. Tamás Nagy In article <dnqil3$26k5$1 digitaldaemon.com>, Tom says...I'm not sure if someone post this before (maybe this is just a copy-paste, I don't recall as I have the d file missed in some directory and I've just found it), but I'm wondering isn't this cast possible? test.d(5): cannot cast int* to ubyte[4] DMD 0.141 Tom
Dec 15 2005
In article <dnrsb9$1l7$1 digitaldaemon.com>, MicroWizard says...I think you just wanted to convert a 32 bit int to it's binary representative. However the mentioned cast should be work somehow, you have to use union for this problem keeping in mind that the result depends on the underlying architecture eg. big or little endianness. On the other hand 'int' is 32 bit now but it is not guaranteed.Oh, yes, int = 32bits it's guaranteed as D defines so in it's specs. With respect to the union alternative, yes I would use a union but this isn't taken from real code, so is just an abstract example to illustrate the issue.In article <dnqil3$26k5$1 digitaldaemon.com>, Tom says...TomI'm not sure if someone post this before (maybe this is just a copy-paste, I don't recall as I have the d file missed in some directory and I've just found it), but I'm wondering isn't this cast possible? test.d(5): cannot cast int* to ubyte[4] DMD 0.141 Tom
Dec 15 2005
On Thu, 15 Dec 2005 01:58:59 +0000 (UTC), Tom wrote:I'm not sure if someone post this before (maybe this is just a copy-paste, I don't recall as I have the d file missed in some directory and I've just found it), but I'm wondering isn't this cast possible? test.d(5): cannot cast int* to ubyte[4]Oops, I got side tracked ;-) Ok so here's an attempt at explaining the problem... The 'cast(ubyte[4])' is telling the compiler to treat the expression that follows as if it was a fixed-size array of 4 ubytes. What follows is '&i' which is the address of an int. So you are asking for the address of an int to be viewed as if it was a block of RAM which is 4 bytes long containing ubytes. But the evaluated expression '&i' is not stored in RAM so the compiler can't paint it with 'ubyte[4]'. -- Derek (skype: derek.j.parnell) Melbourne, Australia "A learning experience is one of those things that says, 'You know that thing you just did? Don't do that.'" - D.N. Adams 16/12/2005 2:19:42 PM
Dec 15 2005
On Fri, 16 Dec 2005 14:25:34 +1100, Derek Parnell <derek psych.ward> wrote:On Thu, 15 Dec 2005 01:58:59 +0000 (UTC), Tom wrote:I don't think "not stored in RAM" is the reason, consider: void main() { uint i; ubyte[4] ub; uint* p = &i; ub[] = cast(ubyte[4])p; //e2ir: cannot cast from uint* to ubyte[4] } ReganI'm not sure if someone post this before (maybe this is just a copy-paste, I don't recall as I have the d file missed in some directory and I've just found it), but I'm wondering isn't this cast possible? test.d(5): cannot cast int* to ubyte[4]Oops, I got side tracked ;-) Ok so here's an attempt at explaining the problem... The 'cast(ubyte[4])' is telling the compiler to treat the expression that follows as if it was a fixed-size array of 4 ubytes. What follows is '&i' which is the address of an int. So you are asking for the address of an int to be viewed as if it was a block of RAM which is 4 bytes long containing ubytes. But the evaluated expression '&i' is not stored in RAM so the compiler can't paint it with 'ubyte[4]'.
Dec 15 2005
On Fri, 16 Dec 2005 16:37:34 +1300, Regan Heath wrote:On Fri, 16 Dec 2005 14:25:34 +1100, Derek Parnell <derek psych.ward> wrote:True ... I think D has made a big mistake in using a single keyword 'cast' to mean 'paint' in some circumstances and 'convert' in others. It is not clear to me when either usage of the keyword is assumed by the compiler. Also, I can't think of a way to override one meaning of 'cast' to mean the other. So it we really did want to paint 'p' in your example with 'ubyte[4]' how is it done? -- Derek (skype: derek.j.parnell) Melbourne, Australia "A learning experience is one of those things that says, 'You know that thing you just did? Don't do that.'" - D.N. Adams 16/12/2005 2:56:37 PMOn Thu, 15 Dec 2005 01:58:59 +0000 (UTC), Tom wrote:I don't think "not stored in RAM" is the reason, consider: void main() { uint i; ubyte[4] ub; uint* p = &i; ub[] = cast(ubyte[4])p; //e2ir: cannot cast from uint* to ubyte[4] } ReganI'm not sure if someone post this before (maybe this is just a copy-paste, I don't recall as I have the d file missed in some directory and I've just found it), but I'm wondering isn't this cast possible? test.d(5): cannot cast int* to ubyte[4]Oops, I got side tracked ;-) Ok so here's an attempt at explaining the problem... The 'cast(ubyte[4])' is telling the compiler to treat the expression that follows as if it was a fixed-size array of 4 ubytes. What follows is '&i' which is the address of an int. So you are asking for the address of an int to be viewed as if it was a block of RAM which is 4 bytes long containing ubytes. But the evaluated expression '&i' is not stored in RAM so the compiler can't paint it with 'ubyte[4]'.
Dec 15 2005
On Fri, 16 Dec 2005 15:12:54 +1100, Derek Parnell <derek psych.ward> wrote:On Fri, 16 Dec 2005 16:37:34 +1300, Regan Heath wrote:I'm not sure you can ever paint something as a static array because you can never assign the result to a static array, because a static array's data pointer is immutable (ignoring the evil hackery you posted) or so it appears to me, eg void main() { uint i; ubyte[4] ub; uint* p = &i; ub = cast(ubyte[4])p; //cannot change reference to static array 'ub' //cannot assign to static array ub } ReganOn Fri, 16 Dec 2005 14:25:34 +1100, Derek Parnell <derek psych.ward> wrote:True ... I think D has made a big mistake in using a single keyword 'cast' to mean 'paint' in some circumstances and 'convert' in others. It is not clear to me when either usage of the keyword is assumed by the compiler. Also, I can't think of a way to override one meaning of 'cast' to mean the other. So it we really did want to paint 'p' in your example with 'ubyte[4]' how is it done?On Thu, 15 Dec 2005 01:58:59 +0000 (UTC), Tom wrote:I don't think "not stored in RAM" is the reason, consider: void main() { uint i; ubyte[4] ub; uint* p = &i; ub[] = cast(ubyte[4])p; //e2ir: cannot cast from uint* to ubyte[4] } ReganI'm not sure if someone post this before (maybe this is just a copy-paste, I don't recall as I have the d file missed in some directory and I've just found it), but I'm wondering isn't this cast possible? test.d(5): cannot cast int* to ubyte[4]Oops, I got side tracked ;-) Ok so here's an attempt at explaining the problem... The 'cast(ubyte[4])' is telling the compiler to treat the expression that follows as if it was a fixed-size array of 4 ubytes. What follows is '&i' which is the address of an int. So you are asking for the address of an int to be viewed as if it was a block of RAM which is 4 bytes long containing ubytes. But the evaluated expression '&i' is not stored in RAM so the compiler can't paint it with 'ubyte[4]'.
Dec 15 2005
On Fri, 16 Dec 2005 17:42:02 +1300, Regan Heath wrote:I'm not sure you can ever paint something as a static array because you can never assign the result to a static array, because a static array's data pointer is immutable (ignoring the evil hackery you posted) or so it appears to me, egA fixed-size array (a.k.a static array) does not have a data pointer. It just sits on the stack as 'x' bytes long.void main() { uint i; ubyte[4] ub;In this case, 'ub' takes up four bytes of stack space. It isn't a pointer to some other four bytes.uint* p = &i; ub = cast(ubyte[4])p; //cannot change reference to static array 'ub' //cannot assign to static array ub }But anyways, I would only do this sort of thing using a union. ---------- import std.stdio; void main() { union iu { uint i; ubyte[i.sizeof] ub; }; iu c; c.i = 1; // access 'c' as a uint writefln("%s", c.ub); // but display 'c' as a ubyte[4] c.i = 22; writefln("%s", c.ub); c.i = 333; writefln("%s", c.ub); c.i = 4444; writefln("%s", c.ub); } ----------- -- Derek (skype: derek.j.parnell) Melbourne, Australia "A learning experience is one of those things that says, 'You know that thing you just did? Don't do that.'" - D.N. Adams 16/12/2005 4:11:16 PM
Dec 15 2005
On Fri, 16 Dec 2005 16:17:32 +1100, Derek Parnell <derek psych.ward> wrote:On Fri, 16 Dec 2005 17:42:02 +1300, Regan Heath wrote:I realise that. A fixed sized array _is_ just a data pointer and that pointer cannot be re-assigned, that was my point.. er ;) But, is this defined in the spec or is this an implementation detail (as James mentions) ReganI'm not sure you can ever paint something as a static array because you can never assign the result to a static array, because a static array's data pointer is immutable (ignoring the evil hackery you posted) or so it appears to me, egA fixed-size array (a.k.a static array) does not have a data pointer. It just sits on the stack as 'x' bytes long.
Dec 15 2005
On Fri, 16 Dec 2005 19:00:42 +1300, Regan Heath wrote:On Fri, 16 Dec 2005 16:17:32 +1100, Derek Parnell <derek psych.ward> wrote:Sorry about this, but my point is that a fixed size array _is_not_ a data pointer. It *is* the data itself, and not a pointer to the data.On Fri, 16 Dec 2005 17:42:02 +1300, Regan Heath wrote:I realise that. A fixed sized array _is_ just a data pointer and that pointer cannot be re-assigned, that was my point.. er ;)I'm not sure you can ever paint something as a static array because you can never assign the result to a static array, because a static array's data pointer is immutable (ignoring the evil hackery you posted) or so it appears to me, egA fixed-size array (a.k.a static array) does not have a data pointer. It just sits on the stack as 'x' bytes long.But, is this defined in the spec or is this an implementation detail (as James mentions)The docs say "a static array always has the dimension statically available as part of the type, and so it is implemented like in C." and from that I read that the length is 'hard coded' in the expressions that refer to the array. Consider this program ... -------------------------- import std.stdio; class Foo { char[9] i; } void main() { union iu { char[9] i; ubyte[i.sizeof] ubi; Foo c; ubyte[c.sizeof] ubc; }; iu c; c.i[0..5] = "abcde"; // update the first 5 slots. writefln("%s", c.ubi); c.c = new Foo; writefln("%s", c.ubc); } =========== Its output is [97,98,99,100,101,255,255,255,255] [224,15,135,0] which is nine bytes. If 'i' was a data pointer it would only be four bytes long. However, 'c' is a pointer and only its four bytes are shown. -- Derek (skype: derek.j.parnell) Melbourne, Australia "A learning experience is one of those things that says, 'You know that thing you just did? Don't do that.'" - D.N. Adams 16/12/2005 6:00:59 PM
Dec 15 2005
Derek Parnell wrote:I think you are both /sorta/ wrong. I have just realized that a static array is in fact *exactly* a const dynamic array. It has exactly the same properties (like .ptr and .length) as a dyn array, only they're const (as in compile-time constant). They do not exist at runtime, except as inlined in code instructions. In fact, nothing of what you said or were thinking was actually wrong (thus the /sorta/), they are just differente but equivalent mental models(so to say), of the same thing. However, this mental model that I just presented is (I think) a more "correct" one. It allows us, for instance, to realize that: char[4] = "1234"; is *exactly* the same as: const char[] = "1234"; It also allows us to explain more clearly why: ub[] = cast(ubyte[4]) p; isn't allowed. Namely, the expression (cast(ubyte[4]) p) doesn't work because the resulting expression would have to be a const dyn array (or let's just call it const array, array being the struct with .ptr and .length ). As such, the resulting .ptr and .length would have to known at compile time. The .length is known, it is 4, as specified by the cast, however, the .ptr would be = p , but since p is not a const value, it doesn't work. Also, as a corolary, it theoretically could work if p was const too. -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."I realise that. A fixed sized array _is_ just a data pointer and that pointer cannot be re-assigned, that was my point.. er ;)Sorry about this, but my point is that a fixed size array _is_not_ a data pointer. It *is* the data itself, and not a pointer to the data.But, is this defined in the spec or is this an implementation detail (as James mentions)The docs say "a static array always has the dimension statically available as part of the type, and so it is implemented like in C." and from that I read that the length is 'hard coded' in the expressions that refer to the array.
Dec 16 2005
Derek Parnell wrote:On Fri, 16 Dec 2005 19:00:42 +1300, Regan Heath wrote:Upon declaration, a static array defines the storage of its contents, but when used as a type, it behaves as a pointer to the data. This is the same behaviour as in C. Consider: void func(char[5] arg) { arg[1] = 'x'; } void main() { char[5] test = "abcd"; func(test); printf(test ~ \n); } Will print "axcd". The contents is not copied when calling the function, the pointer is all that gets passed on. While, as you say, for struct Test { char[5] test; } Test.sizeof will be 5. This behaviour is (as far as I know) unfortunately not replicable in user defined types. I.e. if MyCharArray!(5) made struct Test { MyCharArray!(5) test; } have a size of 5, this function void func(MyCharArray!(5) arg) { ... } would pass the arg by value.On Fri, 16 Dec 2005 16:17:32 +1100, Derek Parnell <derek psych.ward> wrote:Sorry about this, but my point is that a fixed size array _is_not_ a data pointer. It *is* the data itself, and not a pointer to the data.On Fri, 16 Dec 2005 17:42:02 +1300, Regan Heath wrote:I realise that. A fixed sized array _is_ just a data pointer and that pointer cannot be re-assigned, that was my point.. er ;)I'm not sure you can ever paint something as a static array because you can never assign the result to a static array, because a static array's data pointer is immutable (ignoring the evil hackery you posted) or so it appears to me, egA fixed-size array (a.k.a static array) does not have a data pointer. It just sits on the stack as 'x' bytes long.
Dec 19 2005