0

What's the best way of initialzing a const array inside a struct in C?

typedef struct
{
    float coefs[5];

} t_data;

const float ONETWOTHREEFOURFIVE[5] = {1,2,3,4,5};

void init(t_data* data)
{
     data->coefs[0] = ONETWOTHREEFOURFIVE[0];
     data->coefs[1] = ONETWOTHREEFOURFIVE[1];
     ...
}

In real world I have much more than 5 elements.

Is there some better way?

2
  • 1
    Use a for loop, or memcpy. Commented Nov 22, 2016 at 8:45
  • 1
    "...initialzing a const array inside a struct in C" - The target array being initialized isn't const; the source is. Commented Nov 22, 2016 at 8:45

4 Answers 4

4

Assuming you're sure the sizes will be the same, you can use memcpy. I'd also localise the source data as well so it doesn't pollute scope unnecessarily:

void init (t_data* data) {
    static const float srcData[] = {1,2,3,4,5};
    assert (sizeof(data->coeffs) == sizeof(srcData));
    memcpy (data->coeffs, srcData, sizeof(data->coeffs));
}

You'll note I also have an assert in there, this will allow you to detect early whether you're building code that vioaltes the assumption that the two arrays are of the same size. This will avoid buffer overruns on either read or write.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the scope awarness.
You can even make that assert a compile time assert: int comp_assert[sizeof(data->coeffs) == sizeof(srcData) ? 1 : -1];
@selbie +1 for compile time assert, but I would use static_assert from standard library if available.
I think static_assert is C++ only? Does it also exist in C ?
@selbie In C11, they added _Static_assert.
1

You mean initializing the non-const array inside the struct, right?

I think you want this:

memcpy(data->coefs, ONETWOTHREEFOURFIVE, sizeof(ONETWOTHREEFOURFIVE));

Comments

0

My two cents. Assuming that your t_data may contain more stuff than just array of coefficients, you can use dedicated holder-structure and avoid any loop or memcpy().

typedef struct {
    float c[5];
} coef_holder;

static const coef_holder init_set = {
    { 1, 2, 3, 4, 5 }
};

typedef struct
{
    coef_holder coefs;
    /* more stuff */
} t_data;

void init(t_data* data)
{
     data->coefs = init_set;
     ...
}

Also note, this line:

data->coefs = init_set;

is not an initialization, it is an assignment. Of course on some architectures this assignment may be translated into call to memcpy(), but anyway source code looks clearer.

Comments

-1

If you can assign entire structure at once, you could create dummy struct and use assignment:

t_data const ONETWOTHREEFOURFIVE = { {1, 2, 3, 4, 5 } };

void init(t_data* data) {
    *data = ONETWOTHREEFOURFIVE;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.