views:

168

answers:

2

In aid of my one-man quest to populate SO with D questions (=p), I've run into another problem; initialising an array of structs globally. Observe:

struct A
{
    int a;
    float b;
}

A[2] as;
as[0] = {0, 0.0f};
as[1] = {5, 5.2f};

void main() {}

Results in:

$ dmd wtf.d 
wtf.d(8): no identifier for declarator as[0]
wtf.d(9): no identifier for declarator as[1]

Looking through the docs at Digital Mars, I can't really see anything entirely obvious to me, so I turn once more to the brave denizens of Stack Overflow! I'm guessing the error message doesn't have much to do with the real problem, as surely as[0] is an identifier (but dmd thinks it's a declarator, which AFAICT looking over the docs, it isn't)?

+6  A: 

I don't think you can initialise elements on a per-element basis like that. Would this work?

A[2] as = [
    {0, 0.0f},
    {5, 5.2f}
];

Consider what would happen if, in your example, you mentioned as[0] more than once:

as[0] = {0, 0.0f};
as[0] = {1, 1.0f};

What would the value of as[0] be at program initialisation? This is becoming more like statements rather than initialisers.

Note that in D, you can initialise array elements at specific indexes like this:

A[2] as = [
    0: {0, 0.0f},
    1: {5, 5.2f}
];

This would be useful if you have a larger array (such as A[10]) and only need to initialise some of the elements. See Arrays in the D reference documentation for more information.

Greg Hewgill
D'oh. I tried this, but forgot I was using D and did the C-style {{},{}} syntax. Thanks.
Bernard
+1, D expects declarations, and not statements, at the top level of a module. For initial values that can't be computed at compile-time, you could also use a module initialiser.
shambulator
+3  A: 

This also would work if you want to do one-by-one initialization

struct A
{
    int a;
    float b;
}

A[2] as;
as[0] = A(0, 0.0f);
as[1] = A(5, 5.2f);

void main() {}

Every struct gets a default constructor taking each of the args in order if you don't explicitly define a constructor (i.e. static opCall). See StructLiteral

But the down side is this will probably initialize the array to the default value first then change the values one by one. So it'll probably be more efficient to use the actual initialization syntax if you know all the values up front.

Baxissimo
void initialisers (A[2] as = void;) ensure that memory is not initialised. So this is great; thanks.
Bernard