This is what the compiler does by default:
- Allocate a segment in flash containing all init values for every static/global in your program. (Called "rodata" or some such.)
- Copy down these values from flash to your variables, at program startup.
- If you had explicitly initialized a static/global variable, ie "static int x = 5;", the value you wrote will be copied.
- If you didn't explicitly initialize it, the value 0 will be copied. This is required by ISO C.
The answer to your question depends on whether you have set your compiler to use the above method or not. In CW this is called "ANSI startup" or "minimal startup", which you pick when creating a new project. If you pick "ANSI", all your static/global variables will be initialized either to the init value you have written explicitly, or to zero. If you pick "minimal", the only thing the startup code will do is to set the stack pointer and then call main(). Your statics/globals will then not become initialized, even if you explicitly did so. You would have to set them all in runtime.
With ANSI startup code, you will have a for() loop sitting in flash memory, which copies down all init values from flash to RAM. The loop itself doesn't take much flash space, but consumes time at program startup.
With minimal startup, you will not have this loop, but you will have to setup your variables manually instead. With program space in regard, the difference versus "ANSI" will barely be notable.
However, when you do manual assignment of variables, there is a chance that the compiler will optimize the code, particularly for initializing to zero. This will reduce the flash segment of init variables. So in terms of flash memory consumption, you should avoid static/global initialization entirely.
---
Regarding compound literals, I find them as superfluous as designated initializers. Just another thing they just had to include in the language because other languages had similar constructs, even though "anonymous objects" are often considered poor style in those other languages, particularly for complex items such as classes/structs. They make the code cluttered up. Java is known to suffer a lot from it, I remember avoiding anonymous classes like the plauge in Java, just because they weren't readble when the code turned complex. Just look at this snippet:
typedef struct
{
int x;
int y;
}Some_struct;
int func (Some_struct* arg1, int arg2);
...
// Alternative 1, compound literal:
result = func (&(Some_struct){1,2}, 5);
// or if you will, with designated initializers:
result = func (&(Some_struct){.x=1,.y=2}, 5);
// Alternative 2, explicit declaration:
Some_struct ss;
ss.x = 1;
ss.y = 2;
result = func(&ss, 5);To me, alternative 2 is far more readable even for this simple struct with only 2 members. The compound literals have a non-intuitive syntax and they seem mixed up with parameter arg2, which has nothing to do with the struct. The simple truth is: the more you merge non-related operations together on the same row, the messier the code turns out.