31

Is there a way to declare a variable like this before actually initializing it?

    CGFloat components[8] = {
        0.0, 0.0, 0.0, 0.0,
        0.0, 0.0, 0.0, 0.15
    };

I'd like it declared something like this (except this doesn't work):

    CGFloat components[8];
    components[8] = {
        0.0, 0.0, 0.0, 0.0,
        0.0, 0.0, 0.0, 0.15
    };
RyJ
  • 3,995
  • 6
  • 34
  • 54
  • 1
    @PaulTomblin: Not as the OP has suggested, but it is possible to assign to arrays in a few different ways. – dreamlax Jan 16 '12 at 21:27

3 Answers3

36

You cannot assign to arrays so basically you cannot do what you propose but in C99 you can do this:

CGFloat *components;
components = (CGFloat [8]) {
    0.0, 0.0, 0.0, 0.0,
    0.0, 0.0, 0.0, 0.15
};

the ( ){ } operator is called the compound literal operator. It is a C99 feature.

Note that in this example components is declared as a pointer and not as an array.

ouah
  • 142,963
  • 15
  • 272
  • 331
  • This avoids the error alright but It does not populate the array. I am trying to use this idea in Quartz to set default values of two CGFloat arrays to hold color values and it,s not working.; I initialize the pointer static CGFloat * color, then I try this approach and do color = (CGFloat[4]){1.0, 0.0, 0.0, 1.0}; and then call CGContextSetFill(context, color) it does not draw. If I simply do static color[4]; then color[0] = 1.0; color[3] = 1.0 and repeat the fill call , it works as expected. What am I doing wrong? Thanks. – Miek Apr 26 '13 at 15:12
  • this is off-topic, but does this also work with c++? It gives me an `error: taking address of temporary array` – ArchLinuxTux Mar 19 '18 at 07:53
  • 2
    @ArchLinuxTux Compound literals are not supported in C++ (some compilers support it as an extension). – ouah Mar 23 '18 at 11:49
  • @ouah but does it change the address of `components` or is it possible to use this to write an array at a specific address? – user2284570 Jan 07 '21 at 01:02
13

If you wrap up your array in a struct, it becomes assignable.

typedef struct
{
    CGFloat c[8];
} Components;


// declare and initialise in one go:
Components comps = {
    0.0, 0.0, 0.0, 0.0,
    0.0, 0.0, 0.0, 0.15
};


// declare and then assign:
Components comps;
comps = (Components){
    0.0, 0.0, 0.0, 0.0,
    0.0, 0.0, 0.0, 0.15
};


// To access elements:
comps.c[3] = 0.04;

If you use this approach, you can also return Components structs from methods, which means you can create functions to initialise and assign to the struct, for example:

Components comps = SomeFunction(inputData);

DoSomethingWithComponents(comps);

comps = GetSomeOtherComps(moreInput);

// etc.
dreamlax
  • 93,976
  • 29
  • 161
  • 209
  • @ouah but does it change the address of `components` or is it possible to use this to write an array at a specific address? – user2284570 Jan 07 '21 at 01:03
0

That notation for arrays and structs is valid only in initializations, so no.

asaelr
  • 5,438
  • 1
  • 16
  • 22