Dan Laks
Dan Laks

Reputation: 211

Initializing array within structure with another array

I'm writing code in C that initializes a bunch of structures using parts of other structures. For example:

//Original structure
struct
{
    int foo1;
    int foo2;
    int foo3;
} orig_struct = {1,2,3};

//New structure
struct
{
    int bar1;
    int bar2;
} new_struct = {orig_struct.foo1, orig_struct.foo2};

I have to do this for a lot of structures, and the initialization method above makes the code look very clean and readable. To be clear, I don't have any control over the original structures. I'm just creating the new structures to capture data from them.

I ran into an issue when one of the structures had a large array:

//Original structure
struct
{
    int foo1;
    int foo2[50];
    int foo3;
} orig_struct = {1,{2,3,etc},52}; //<--replace "etc" with 48 more int values

//New structure
struct
{
    int bar1;
    int bar2[50];
} new_struct = {orig_struct.foo1, XXX};

Is there anything I can replace XXX with to initialize the array in the new structure with the values in the array of the original structure? Again, I'd like to keep a clean, consistent look to my code, so keeping it within the curly brackets would be ideal. I know I can manually type out each element of the array within their own curly brackets:

...
} new_struct = {orig_struct.foo1, {orig_struct.foo2[0],orig_struct.foo2[1],orig_struct.foo2[2],orig_struct.foo2[3],etc}

But it's pretty obvious why that can quickly become untenable.

Upvotes: 3

Views: 2634

Answers (2)

jxh
jxh

Reputation: 70502

Note that your syntax for initializing new_struct does not work if new_struct has static storage duration, since a constant expression is required in that case.

There really isn't any way to directly assign an array to another array. This is only allowed if the array itself is encapsulated by a structure, and you are using structure assignment. Since your original structure and new structure share a common initial prefix, you could try to exploit this through a union:

struct orig_struct_type orig_struct = {1,{2,3},52};

void some_function ()
{
    union {
        struct orig_struct_type o;
        struct new_struct_type n;
    } *u = (void *)&orig_struct;
    struct new_struct_type new_struct = u->n;
    /* ... */
}

If you are simply trying to reduce code duplication, you can place the array initializer list into a macro.

#define VALUES {2,3,etc} //<--replace "etc" with 48 more int

//Original structure
struct
{
    int foo1;
    int foo2[50];
    int foo3;
} orig_struct = {1,VALUES,52};

void some_function ()
{
    struct
    {
        int bar1;
        int bar2[50];
    } new_struct = {orig_struct.foo1, VALUES};
    /* ... */
}

Upvotes: 3

Stephan Lechner
Stephan Lechner

Reputation: 35164

In c, I see no way to do this within an initializer, as assigning an array is not supported, and expressions must be constant expressions; so a loop or memcpy is not possible during initialization (cf. array initialization reference):

As with all other initialization, every expression in the initializer list must be a constant expression when initializing arrays of static or thread-local storage duration:

Later on, of course, you could write memcpy(new_struct.bar2, orig_struct.foo2, sizeof(new_struct.bar2)), but this code is then separated from the struct/variable declaration.

Upvotes: 2

Related Questions