Skip to content

Initializing a vanilla C struct

An answer to this question on Stack Overflow.

Question

I want to add a C-style struct to a C++ header and use it in a C function. But this is not working:

struct Vertex {
float Position[2];
float Color[4];
};
struct Square{
Vertex vertices[4];
};

Elsewhere:

float color[4]={rColor, gColor, bColor, alpha};
float halfsize=(float)size/2;
Square square= {
    {{halfsize,halfsize},{color[0],color[1],color[2],color[3]}},
    {{halfsize,-halfsize},{color[0],color[1],color[2],color[3]}}, //error on this line
    {{-halfsize,-halfsize},{color[0],color[1],color[2],color[3]}},
    {{-halfsize,halfsize},{color[0],color[1],color[2],color[3]}}
};

Reports "Excess elements in struct initializer" on the second line.

On a related note, is there a more efficient way to pass in the array color to the square set?

Answer

As the other answerer has mentioned, you should add an extra brace and then things will work.

However, you also ask if this is a more efficient way to pass in color.

I'm afraid I don't think there there is. Since neither C nor C++ keep track of the length of an array and since there is no construct for splicing arrays you cannot indicate to the compiler that you want a certain section of the array to be copied.

But what do you really mean by efficient? If you mean, "Is there a way which will execute faster?" Then the answer is almost certainly no. This initialization will be very quick.

If you mean, "Is there a way which can be written with fewer lines of code?" Then the answer again is probably no. Six lines is pretty tight.

Granted, you are using a C++ header, so I'd think you must also be using a C++ compiler so it seems pointless to build this part of the code in pure C. You could make color into an STL vector and then build some constructors for Square and Vertex which initialize off of this vector. It would not take significantly more code and may reduce the probability of accidental mistakes.

Alternatively, if you're set on C and plan on having this code come up time and again, you could consider using a macro (either as below, or for the whole bloody thing, but then I'd say it would be better to have it in a function):

#define RGB_INIT {color[0],color[1],color[2],color[3]}

Though macros do have their dangers.