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

发布于 2024-12-04 02:56:14 字数 499 浏览 1 评论 0原文

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

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 };

它抱怨 FooZero 的使用,指出 FooZero 不是一个编译时常量

但不是吗?我在这里不明白什么?

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

谢谢

I'm curious why the following code snippet doesn't compile:

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 };

It complains about the use of FooZero, stating that FooZero isn't a Compile-Time Constant

But isn't it? What am I not understanding here?

Obviously, I can simply replace the use of FooZero in the initializer with { 0, 0 } - my purpose in asking the question is not how to get around the problem - I'm trying to understand the underlying reason why FooZero is not, in fact, a compile-time constant.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

咿呀咿呀哟 2024-12-11 02:56:14

它主要与初始化有关。

初始化的变量通常不是通过“将此值放入该位置”的代码来初始化的,而是通过加载特定值范围的定义(分别是 .data)来初始化。 .rodata 段,到它应该在的内存位置。这是由操作系统文件加载器完成的。 (严格来说,这不是 C 的属性,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)。

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).

迟到的我 2024-12-11 02:56:14

在 C 语言中,conststatic const 值不被视为“编译时常量”,而

#define FooZero  {0, 0}

被视为编译时常量。你可能会说“但是但是,它甚至说const!它怎么可能不是一个常量呢?”事实上,该语言表示您不能更改指定为 const 的值,但您也不能将其用作初始值设定项。您可以问为什么您喜欢,它不会改变语言定义它的方式 - 尽管您的编译器可能会为您提供更改此行为的选项,并且在任何情况下都不难解决。

我认为 C 编译器将静态常量视为全局变量是很常见的 - 也就是说,实际为变量(永远不会改变)分配空间,而不是将硬值编程到机器代码中,就像您执行以下操作一样#define。在这种情况下,常量确实如编译器所说,不是编译时常量,尽管它们在初始化后(在运行时)是用于所有其他目的的常量。

In the C language a const or static const value is not considered a "compile time constant", whereas

#define FooZero  {0, 0}

is considered to be a compile-time constant. You may say "But but, it even says const! How can it not be a constant??" And indeed the language says you cannot change the value of a thing you specify as const, but you also cannot use it as an initializer. You can ask why all you like, it won't change how the language defines it - although your compiler may give you an option to change this behaviour, and it is not too hard to work around in any case.

I think it is quite common for C compilers to treat static constants like global variables - that is, to actually allocate space for a variable (which never changes), rather than program the hard values into the machine code as it would if you did a #define. In this case the constants, indeed as the compiler says, are not compile-time constants, although they are constants for all other purposes after they are initialised (at runtime).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文