【问题标题】:Assigning members of a const variable to another const将 const 变量的成员分配给另一个 const
【发布时间】:2017-01-12 03:14:39
【问题描述】:

我正在尝试定义两个具有相同数据结构的const 变量。我想确保每个变量的所有成员都完全相同,除了我要更改的那个。由于我不想维护相同代码的两个完全相同的副本,我想“为什么不使用一个中的现有成员来初始化另一个?”

下面是代码示例:

typedef struct {
    int a;
    int b;
} aStruct;

const aStruct foo = {
    .a = 10,
    .b = 20
};

const aStruct bar = {
    .a = 15,
    .b = foo.b
};

当我尝试编译这段代码时,我得到一个错误:

foo.c:13:14: error: initializer element is not constant
         .b = foo.b
              ^~~
foo.c:13:14: note: (near initialization for ‘bar.b’)

我是 C 的新手,所以我不完全理解常量和数据结构的工作原理,尤其是当它们放在一起时。有人可以帮我弄清楚这里发生了什么吗?

【问题讨论】:

  • 使用#define 共享一个值。
  • 这是一个棘手的领域,但我认为问题在于const 并不像您希望的那样恒定。在文件范围(相对于函数范围),你不能写:static const int N = 100;static aStruct as_array[N];; N 的值不被认为是编译时常量,数组大小必须是编译时常量。在类似的情况下,您通常可以将地址用作初始化程序,因为地址是固定的(由链接器 - “编译时”处理的最后阶段)。但我认为您遇到了这个“const 不是真的恒定”的问题。
  • 我所说的推论:你也不能使用static aStruct as_data[foo.a];——在这种情况下,既不能在文件范围内,也不能在函数范围内(但删除static,它会在功能范围内很好)。另见static const vs #define vs enum in C。这不是重复的,但它可能会为您所面临的问题提供一些启示。
  • 你的标题已经说过了:“分配一个 const variable 的成员 ...”。 C 没有符号常量(枚举常量除外)。
  • 你的意图很清楚:foo.b 已经被初始化了,为什么编译器不使用那个值呢?但请注意.b = foo.b需要指令(获取foo的地址,添加b的偏移量,获取b的值)并且指令只能在函数中执行。

标签: c struct constants


【解决方案1】:

这是因为您试图在文件范围内初始化全局变量,并且在该范围内只有常量(foo.b 不是)可用于初始化值。我的编译器给出了更好的信息:

error: initializer element is not a compile-time constant
    .b = foo.b
         ~~~~^ 1 error generated.

如果您尝试在块范围内做同样的事情,那将是正确的:

typedef struct {
    int a;
    int b;
} aStruct;

int main() {
  const aStruct foo = {
    .a = 10,
    .b = 20
  };

  const aStruct bar = {
    .a = 15,
    .b = foo.b
  };
}

所以,你最好使用一些定义来将你的全局变量初始化为相同的值。

【讨论】:

  • 我对该解决方案有疑问。实际应用程序中结构的成员本身就是结构,因此使用#defines 非常困难。但是,它确实回答了我给出的示例,所以谢谢!
  • @AdamGausmann:有可以使用的复合文字和指定的初始值设定项(struct WhatEver){ .we_member1 = VALUE1, .we_member3 = VALUE3 } 等。可以包装在#define 中。或者也许您应该使用指向其他(常量)结构的(常量)指针?或者某种组合。我不喜欢#define,但如果要重复多次,使用宏来避免重复是个好主意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-15
  • 2019-09-02
相关资源
最近更新 更多