使用其他Const Struct实例初始化Const Struct

Ste*_*eve 10 c struct initialization

我很好奇为什么下面的代码片段无法编译:

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 };
Run Code Online (Sandbox Code Playgroud)

它抱怨使用FooZero,说明FooZero不是Compile-Time Constant

但不是吗?我在这里不理解什么?

显然,我可以简单地替换FooZero初始化程序中的用法{ 0, 0 }- 我的目的是提出问题不是如何解决问题 - 我试图理解其根本原因FooZero不是,实际上是编译时常量.

谢谢

glg*_*lgl 10

它主要与初始化有关.

初始化变量通常不是由代码表示的,该代码表示​​"将此值放到该位置",而是通过加载特定值范围的定义,即.dataresp..rodata段,到它应该是的内存位置.这是由OS文件加载器完成的.(严格来说,这不是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 };
Run Code Online (Sandbox Code Playgroud)

或者反过来说:

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...
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,您必须BarZero.foo使用->(像BarZero.foo->a)访问的组件,

在第二种情况下,你必须FooZero使用->(像FooZero->a)访问的组件.