Nameless Static Array

monarch_dodra via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Jun 12 09:45:35 PDT 2014


On Thursday, 12 June 2014 at 15:58:25 UTC, Taylor Hillegeist 
wrote:
> So, Lately I have been avoiding the NEW keyword.

Why? Is malloc OK?

> I have recently given up static allocation of classes using 
> CTFE. I guess they must be const or immutable?

Funny, because you *are* allowed to default initialized a class 
member variable to a static class instance. And basically, it's 
just a thread local global. So you can "work around" with:

//----
class MyClass
{
     int i = 5;
}

void main() {
     static struct S
     {
         MyClass g = new MyClass();
     }
     static S s;
     writeln(s.g.i);
}
//----

Disclaimer: Not sure if actually legal, or will cease to work in 
a few releases.

> So naturally i can do most of what i need to with structs. They 
> are statically allocated no NEW necessary. But without the NEW 
> strategy. I must allocate static arrays and set them to a 
> pointer in my struct. Not too big of deal really.
>
> 	uint[12] Buffer;
> 	R_R_Buffer RRB=R_R_Buffer(Buffer);
> 	
> 	uint[24] OtherBuffer;
> 	R_R_Buffer RRB2 = R_R_Buffer(OtherBuffer);
>
> I feel though i might end up having OtherOtherOtherBuffers, and 
> it pollutes my local symbols. I just dont like it.
>
> Is there a way to not give the buffer a name and do lika dis:
>
> 	R_R_Buffer RRB=R_R_Buffer(uint[12]);
> 	R_R_Buffer RRB2 = R_R_Buffer(uint[24]);
>
> This obviously fails to compile, but i think you get the idea. 
> Mostly, I don't care what the static array name is.

If you have a pointer, then at the end of the day *someone* 
*somewhere*, is going to have to declare and hold the buffers. 
That said, you could simply have a *single* static array that 
holds all your data. Furthermore, you could package it into a 
single convenient struct package:

struct Buffer(T, size_t N)
{
     T[N] buffer;
     size_t used;
     T[] getBufferSlice(size_t n) {
         assert(used + n <= N, "You've overused your buffer!");
         auto low = used;
         used += n;
         return buffer[low .. used];
     }
     ref T[n] getBufferSlice(size_t n)() {
         return *cast(T[n]*) getBufferSlice(n).ptr;
     }
}

void main()
{
     Buffer!(int, 36) myData;
     int[] a    = myData.getBufferSlice(12);
     int[24]* p = &myData.getBufferSlice!24();
}

Notice that with this approach, you can extract a dynamic slice 
referencing stack data, if you don't know the size you want. If 
you statically know the size you want, then you can call your 
function template style, and have a more strongly typed return 
value, that can be passed by ref.


More information about the Digitalmars-d-learn mailing list