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)访问的组件.