December 16, 2005 Re: Not sure | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | 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'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
>
> A fixed-size array (a.k.a static array) does not have a data pointer. It
> just sits on the stack as 'x' bytes long.
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)
Regan
|
December 16, 2005 Re: Not sure | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | 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: >> 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, eg >> >> A fixed-size array (a.k.a static array) does not have a data pointer. It just sits on the stack as 'x' bytes long. > > 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. 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 |
December 16, 2005 Dynamic Array ABI: Whoa.. ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | 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." |
December 16, 2005 Re: Dynamic Array ABI: Whoa.. ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bruno Medeiros | In article <dnv1p9$2gv0$1@digitaldaemon.com>, Bruno Medeiros says... > >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. [...] 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; |
December 16, 2005 Dynamic Arrays and Static Arrays | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell 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 ;) > > > 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. > 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." |
December 16, 2005 Re: Dynamic Array ABI: Whoa.. ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bruno Medeiros | Bruno Medeiros wrote:
> 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.
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.
Sean
|
December 17, 2005 Re: Dynamic Array ABI: Whoa.. ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote: > Bruno Medeiros wrote: > >> 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. > > > Switching them would break the ability to do this: > > char[] buf; > printf( "%.*s", buf ); > 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." |
December 18, 2005 Re: Dynamic Array ABI: Whoa.. ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bruno Medeiros | Bruno Medeiros wrote:
> Sean Kelly wrote:
>
>> Bruno Medeiros wrote:
>>
>>> 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.
>>
>>
>>
>> Switching them would break the ability to do this:
>>
>> char[] buf;
>> printf( "%.*s", buf );
>>
> 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.
>
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.
|
December 19, 2005 Re: Dynamic Array ABI: Whoa.. ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to James Dunne | 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
|
December 19, 2005 Re: Not sure | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote:
> 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:
>>
>>>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, eg
>>>
>>>A fixed-size array (a.k.a static array) does not have a data pointer. It
>>>just sits on the stack as 'x' bytes long.
>>
>>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.
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.
|
Copyright © 1999-2021 by the D Language Foundation