It has mainly to do with initialization.
The initialized variables are usually not initialized by code which says "put this value to that location", but by a definition which loads a specific value range, the .data
resp. .rodata
segment, to the memory location where it is supposed to be. This is done by the OS file loader. (Strictly speaking, this is not a property of C, which doesn't know anything about that, but of the execution environment.)
That said, it is not possible to tell a part of this memory area to be copied from another one. But it would be possible that te compiler itselfs recognizes the intent of the declaration and puts the same values to diefferent locations. But that would probably be too much "guessing".
In your case: Wouldn't a pointer to FooZero
maybe a better solution? The values are both the same...
typedef struct Foo {
int a;
int b;
} Foo;
static const Foo FooZero = { 0, 0 };
typedef struct Bar {
Foo * foo;
int c;
} Bar;
static const Bar BarZero = { &FooZero, 0 };
Or the other way round:
typedef struct Foo {
int a;
int b;
} Foo;
typedef struct Bar {
Foo foo;
int c;
} Bar;
static const Bar BarZero = { { 0, 0 }, 0 };
static const Foo * FooZero = &BarZero.foo; // if that is possible, untested...
In the first case, you would have to access BarZero.foo
's components with ->
(like BarZero.foo->a
),
in the second case you would have to access FooZero
's components with ->
(like FooZero->a
).