Is there a way to initialize the whole array of structures (maybe using compound literals) after it is being declared?
typedef struct
{
int a;
int b;
} tStruct;
/* Array of structures in declared in global scope, but not initialized */
tStruct myStruct[3];
void init()
{
/* We want to initizlize the array with specific values*/
/* using compound literals to initialize the whole array doesn't work */
myStruct = (tStruct[])
{
{1, 2},
{3, 4},
{5, 6}
};
}
Arrays aren't R values, so you can't copy them via assignemnt. But you can use memcpy
#include <string.h>
void init(void)
{
memcpy(&myStruct,(tStruct[]) { {1, 2}, {3, 4}, {5, 6} }, sizeof(myStruct));
}
The code generated by an optimizing compiler shouldn't be much worse than what you'd get with
void init2(void)
{
myStruct[0] = (tStruct){1,2};
myStruct[1] = (tStruct){3,4};
myStruct[2] = (tStruct){5,6};
}
or
void init3(void)
{
myStruct[0].a = 1, myStruct[0].b = 2;
myStruct[1].a = 3, myStruct[1].b = 4;
myStruct[2].a = 5, myStruct[1].b = 6;
}
Gcc and clang are well capable of eliding an unnecessary compound variable like that in favor of assigning individual components directly.
https://gcc.godbolt.org/z/j9f37j
The biggest downside of the memcpy
approach is that it's a bit brittle and type-unsafe (and can result in out-of-bounds reads/writes if the unenforced type compatibility is violated).
If your C dialect has __typeof, then with some macro trickery you should be able to almost get around this C language limitation:
#include <string.h>
#define assignAnything(DestPtr,SrcPtr) ((void)((__typeof(SrcPtr)){0} = (__typeof(DestPtr)){0}) /*typecheck*/, memcpy(DestPtr, SrcPtr, sizeof(*(DestPtr))))
/* A Ptr-less version:
#define assignAnything2(Dest,Src) ((void)((__typeof(&(Src))){0} = (__typeof(&(Dest))){0}), memcpy(&(Dest), &(__typeof(Src)){Src}, sizeof(Dest)))
doesn't always work, unfortunately */
int main()
{
int d[3][2][1]={0};
int const s[3][2][1] = {0};
assignAnything(&d,&s); //works
#if NOPE
assignAnything(&s,&d); //will (correctly) compile-time fail because s has more qualifs (const) than d
#endif
}