В основном это связано с инициализацией.
Инициализированные переменные обычно инициализируются не кодом, который говорит «поместите это значение в это место», а определением, которое загружает определенный диапазон значений, .data
соответственно. .rodata
сегмент, к месту памяти, где он должен быть. Это делается загрузчиком файлов ОС. (Строго говоря, это не свойство C, которое ничего об этом не знает, а среда исполнения.)
Тем не менее, невозможно сказать, чтобы часть этой области памяти была скопирована из другой. Но было бы возможно, чтобы сам компилятор распознал цель объявления и поместил те же значения в разные места. Но это, вероятно, было бы слишком много "догадок".
В вашем случае: разве указатель на FooZero
не может быть лучшим решением? Значения одинаковы ...
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 };
Или наоборот:
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...
В первом случае вам нужно будет получить доступ к компонентам BarZero.foo
с помощью ->
(например, BarZero.foo->a
),
во втором случае вам придется обращаться к компонентам FooZero
с помощью ->
(например, FooZero->a
).