www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Allocating a fixed-size array on the heap

reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
So, in the process of answering another thread, I realized that it doesn't 
entirely seem possible to allocate a fixed-size array on the heap through 
normal means.  That is,  the following is legal:

float[4] a;
float[4]* b = &a;

But:

float[4]* c = new float[4];

"Waiit," says the compiler, "the type of 'new float[4]' is float[]."

So here some syntactic sugar is getting in the way of writing what I mean!

I've come up with this:

T* alloc(T)()
{
    struct S
    {
        T t;
    }

    return &(new S).t;
}

..

float[4]* d = alloc!(float[4]);

but that seems awfully hackish.

Am I missing something or is this just yet another instance of how 
fixed-size arrays aren't treated as first-class citizens? 
Jan 30 2008
next sibling parent reply "David Wilson" <dw botanicus.net> writes:
On 1/30/08, Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:
 So, in the process of answering another thread, I realized that it doesn't
 entirely seem possible to allocate a fixed-size array on the heap through
 normal means.  That is,  the following is legal:

 float[4] a;
 float[4]* b = &a;

 But:

 float[4]* c = new float[4];

 "Waiit," says the compiler, "the type of 'new float[4]' is float[]."

 So here some syntactic sugar is getting in the way of writing what I mean!

 I've come up with this:

 T* alloc(T)()
 {
     struct S
     {
         T t;
     }

     return &(new S).t;
 }

 ..

 float[4]* d = alloc!(float[4]);

 but that seems awfully hackish.

As I understand it, a variable of the type float[4] will already be a reference pointing to the heap. The pointer syntax I do not understand, and it doesn't seem particularly well documented. As I understand it, float[4] a = new float[4]; float[4]* b = &a; b is a word-sized pointer to a, which is 2 words (ptr, length). The first word, ptr, is pointing to the heap.
 Am I missing something or is this just yet another instance of how
 fixed-size arrays aren't treated as first-class citizens?

Either you're missing something or I am. I think the pointer support is purely for C compatibility (but I may be terribly wrong).

Jan 30 2008
next sibling parent Regan Heath <regan netmail.co.nz> writes:
David Wilson wrote:
 As I understand it, a variable of the type float[4] will already be a
 reference pointing to the heap. The pointer syntax I do not
 understand, and it doesn't seem particularly well documented.
 
 As I understand it,
 
    float[4] a = new float[4];
    float[4]* b = &a;
 
 b is a word-sized pointer to a, which is 2 words (ptr, length). The
 first word, ptr, is pointing to the heap.
 Am I missing something or is this just yet another instance of how
 fixed-size arrays aren't treated as first-class citizens?

Either you're missing something or I am. I think the pointer support is purely for C compatibility (but I may be terribly wrong).

A static array like "float[4] a;" isn't the same as a dynamic one in that it's not a struct in the form (ptr, length). Instead, as the compiler which knows the length at compile time replaces all instances of "a.length" with an actual constant value, you can see that from this example: import std.stdio; void main() { float[4] a; uint* pl = &a.length; //Error: constant 4u is not an lvalue } R
Jan 30 2008
prev sibling parent downs <default_357-line yahoo.de> writes:
David Wilson wrote:
 As I understand it, a variable of the type float[4] will already be a
 reference pointing to the heap.

No. Because the size is part of the type (float[4]), there's no reason to store it separately. And since float[4] is a value type, not a reference type like ordinary arrays, it's allocated on the stack. The trouble is, because you can allocate dynamic arrays via the `new T[n]` syntax (which, incidentally, has nothing to do with static arrays), there's no syntax left over for allocating float[4] on the heap. However, since static arrays are a stunted data type anyway (can't return them, can't ref them), I recommend that they only be used wrapped in a struct, where they can be handled safely. --downs
Jan 30 2008
prev sibling next sibling parent reply Don Clugston <dac nospam.com.au> writes:
Jarrett Billingsley wrote:
 So, in the process of answering another thread, I realized that it doesn't 
 entirely seem possible to allocate a fixed-size array on the heap through 
 normal means.  That is,  the following is legal:
 
 float[4] a;
 float[4]* b = &a;
 
 But:
 
 float[4]* c = new float[4];
 
 "Waiit," says the compiler, "the type of 'new float[4]' is float[]."
 
 So here some syntactic sugar is getting in the way of writing what I mean!

I don't think it's just a syntax sugar problem. You can write: alias float[4] Foo; Foo * c = new Foo; which generates the error message: Error: new can only create structs, dynamic arrays or class objects, not float[4u]'s
 Am I missing something or is this just yet another instance of how 
 fixed-size arrays aren't treated as first-class citizens? 

The error message isn't correct -- you can also 'new' primitive types. But you can't new an associative array, either; so AAs are also second-class.
Jan 30 2008
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Don Clugston" <dac nospam.com.au> wrote in message 
news:fnqdk0$1lei$1 digitalmars.com...

 I don't think it's just a syntax sugar problem.
 You can write:
 alias float[4] Foo;
 Foo * c = new Foo;

 which generates the error message:
 Error: new can only create structs, dynamic arrays or class objects, not 
 float[4u]'s

:P How convenient.
Jan 30 2008
prev sibling parent reply "Janice Caron" <caron800 googlemail.com> writes:
On Jan 30, 2008 2:45 PM, Jarrett Billingsley <kb3ctd2 yahoo.com> wrote:
 So, in the process of answering another thread, I realized that it doesn't
 entirely seem possible to allocate a fixed-size array on the heap through
 normal means.  That is,  the following is legal:

 float[4] a;
 float[4]* b = &a;

 But:

 float[4]* c = new float[4];

I guess you could always do struct FixedSizeArray(T,uint N) { T[N] array; } float[4]* c = &(new FixedSizeArray!(float,4)()).array; ?
Jan 31 2008
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Janice Caron" <caron800 googlemail.com> wrote in message 
news:mailman.47.1201766463.5260.digitalmars-d puremagic.com...

 I guess you could always do

    struct FixedSizeArray(T,uint N) { T[N] array; }
    float[4]* c = &(new FixedSizeArray!(float,4)()).array;

 ?

Come _on_! You really need to start reading my posts the whole way through!
Jan 31 2008