digitalmars.D - Minor issue - zero-length fixed size arrays in variable-sized
- Jarrett Billingsley (14/14) Jul 08 2009 I noticed in the spec on arrays that "A [fixed-size] array with a
- bearophile (6/8) Jul 08 2009 The future most important implementation of D, LDC, allocates a "bit" fo...
- Tim Matthews (33/36) Jul 08 2009 It would be interesting if anyone has yet to find this useful. In c it
- Daniel Keep (20/20) Jul 08 2009 You'd have to be mad to use it like that.
- Tim Matthews (3/26) Jul 08 2009 I don't know what you'd have to be to use it like that though ^ :)
- Jarrett Billingsley (6/26) Jul 09 2009 You can't. The rest of my post explains that T[0].ptr is always null,
- Steven Schveighoffer (6/21) Jul 09 2009 ...
- Jarrett Billingsley (3/5) Jul 09 2009 Nope; &data is a char[0]*, and slicing it will get you a char[0][].
- Steven Schveighoffer (10/17) Jul 10 2009 d'oh!
- Tim Matthews (2/6) Jul 10 2009 Have you reported this issue as a bug/enhancement?
- Joakim (9/34) Mar 29 2015 Just thought I'd mention that this works now, since this is the
I noticed in the spec on arrays that "A [fixed-size] array with a dimension of 0 is allowed, but no space is allocated for it. It's useful as the last member of a variable length struct.." This sounds like C99's "flexible array members," where a struct can have an array as its last element that isn't given a size, specifically for allowing variable-sized structs. Well, the issue with a zero-length fixed-size array is that.. uh, you can't access anything out of it. The compiler disallows any indexing of a zero-length array with constant indices, and at runtime, all accesses caught by the array bounds checking. Weirder still, the .ptr of any zero-length array is always null, so you can't even do things like "arr.ptr[5] = x;" (which would be perfectly acceptable in my opinion). Just a silly issue.
Jul 08 2009
Jarrett Billingsley: I have "solved" that problem compiling in release mode...I noticed in the spec on arrays that "A [fixed-size] array with a dimension of 0 is allowed, but no space is allocated for it.The future most important implementation of D, LDC, allocates a "bit" for it (I have no idea where this bit goes): http://www.dsource.org/projects/ldc/wiki/Docs#Zero-lengthstaticarrays Bye, bearophile
Jul 08 2009
Jarrett Billingsley wrote:I noticed in the spec on arrays that "A [fixed-size] array with a dimension of 0 is allowed, but no space is allocated for it. It's useful as the last member of a variable length struct.." .......It would be interesting if anyone has yet to find this useful. In c it could be used more directly. In D I think its not much use apart from the offset of property. It would be real bad to have to use it like this: import std.stdio; struct S { int a; uint msgSize; char[0] message; } void setMessage(S* s, const char[] msg) { (cast(char*)(s+S.message.offsetof))[0..s.msgSize] = msg[0..s.msgSize]; } char[] getMessage(S* s) { return (cast(char*)(s+S.message.offsetof))[0..s.msgSize]; } S* createS(uint msgSize) { S* s = cast(S*)((new ubyte[S.sizeof+msgSize]).ptr); s.msgSize = msgSize; return s; } void main() { S* s = createS(5); setMessage(s, "hello"); writeln(getMessage(s)); setMessage(s, "world"); writeln(getMessage(s)); }
Jul 08 2009
You'd have to be mad to use it like that. struct S { int a; private { size_t size; char[0] data; } char[] message() { return data.ptr[0..length]; } size_t length() { return size; } S* opCall(size_t size) { return cast(S*)((new ubyte[S.sizeof+size]).ptr); } } void main() { auto s = S(5); s.message[] = "hello"; writeln(s.message); s.message[] = "world"; writeln(s.message); }
Jul 08 2009
Daniel Keep wrote:You'd have to be mad to use it like that.I am mad.struct S { int a; private { size_t size; char[0] data; } char[] message() { return data.ptr[0..length]; } size_t length() { return size; } S* opCall(size_t size) { return cast(S*)((new ubyte[S.sizeof+size]).ptr); } } void main() { auto s = S(5); s.message[] = "hello"; writeln(s.message); s.message[] = "world"; writeln(s.message); }I don't know what you'd have to be to use it like that though ^ :)
Jul 08 2009
On Thu, Jul 9, 2009 at 2:38 AM, Daniel Keep<daniel.keep.lists gmail.com> wr= ote:You'd have to be mad to use it like that. struct S { =A0 =A0int a; =A0 =A0private { size_t size; char[0] data; } =A0 =A0char[] message() { return data.ptr[0..length]; } =A0 =A0size_t length() { return size; } =A0 =A0S* opCall(size_t size) =A0 =A0{ =A0 =A0 =A0 =A0return cast(S*)((new ubyte[S.sizeof+size]).ptr); =A0 =A0} } void main() { =A0 =A0auto s =3D S(5); =A0 =A0s.message[] =3D "hello"; =A0 =A0writeln(s.message); =A0 =A0s.message[] =3D "world"; =A0 =A0writeln(s.message); }You can't. The rest of my post explains that T[0].ptr is always null, for some reason. Currently I'm doing almost the same thing, though (cast(char*)(this + 1)[0 .. size]).
Jul 09 2009
On Thu, 09 Jul 2009 09:47:44 -0400, Jarrett Billingsley <jarrett.billingsley gmail.com> wrote:On Thu, Jul 9, 2009 at 2:38 AM, Daniel Keep<daniel.keep.lists gmail.com> wrote:...You'd have to be mad to use it like that. struct S { int a; private { size_t size; char[0] data; } char[] message() { return data.ptr[0..length]; }Would something like this work? (&data)[0..length] -SteveYou can't. The rest of my post explains that T[0].ptr is always null, for some reason. Currently I'm doing almost the same thing, though (cast(char*)(this + 1)[0 .. size]).
Jul 09 2009
On Thu, Jul 9, 2009 at 1:09 PM, Steven Schveighoffer<schveiguy yahoo.com> wrote:Would something like this work? (&data)[0..length]Nope; &data is a char[0]*, and slicing it will get you a char[0][]. Which is pretty useless :D
Jul 09 2009
On Thu, 09 Jul 2009 20:24:16 -0400, Jarrett Billingsley <jarrett.billingsley gmail.com> wrote:On Thu, Jul 9, 2009 at 1:09 PM, Steven Schveighoffer<schveiguy yahoo.com> wrote:d'oh! Yeah, the only improvement I can make on your code then is: (cast(char*)&data)[0..length]; Or the more general: (cast(typeof(data[0])*)&data)[0..length] Which still involves a cast. Crappy. Having the compiler do the right thing is a much better option :) -SteveWould something like this work? (&data)[0..length]Nope; &data is a char[0]*, and slicing it will get you a char[0][]. Which is pretty useless :D
Jul 10 2009
Steven Schveighoffer wrote:Having the compiler do the right thing is a much better option :) -SteveHave you reported this issue as a bug/enhancement?
Jul 10 2009
On Wednesday, 8 July 2009 at 22:55:47 UTC, Jarrett Billingsley wrote:I noticed in the spec on arrays that "A [fixed-size] array with a dimension of 0 is allowed, but no space is allocated for it. It's useful as the last member of a variable length struct.." This sounds like C99's "flexible array members," where a struct can have an array as its last element that isn't given a size, specifically for allowing variable-sized structs. Well, the issue with a zero-length fixed-size array is that.. uh, you can't access anything out of it. The compiler disallows any indexing of a zero-length array with constant indices, and at runtime, all accesses caught by the array bounds checking. Weirder still, the .ptr of any zero-length array is always null, so you can't even do things like "arr.ptr[5] = x;" (which would be perfectly acceptable in my opinion). Just a silly issue.Just thought I'd mention that this works now, since this is the only forum thread that mentions working with C's flexible array members. You simply define a zero-length array and then access it using .ptr, as in this C binding and example program I recently translated: https://github.com/joakim-noah/usrsctp/blob/master/usrsctp.d#L185 https://github.com/joakim-noah/usrsctp/blob/master/programs/rtcweb.d#L836
Mar 29 2015