【问题标题】:Static initialization in CC中的静态初始化
【发布时间】:2023-03-31 11:43:01
【问题描述】:

我想要看起来像这样的代码...

static linked_list* globalListHoldingAllSortsOfGoodies = initialize_linked_list();

/* [In a different file...] */
static int placeholder = add_to_global_list(goodies);

但是非常量初始化在 C 中是不可能的。

有没有办法在不破坏 C89 的情况下获得相同的效果?

关键是通过使用同样使用占位符的宏声明好东西,让不同的东西“自动注册”到全局列表中。

【问题讨论】:

  • 你的意思是“不破坏C99”吗?
  • 你说的这个 c98 是什么?
  • 请检查您在使用非常不受欢迎的标签时是否打错字。(c98 仅标记了 1 个其他问题,虽然我似乎找不到)
  • 对不起,我今天一定有一点阅读障碍。我修复了标签。

标签: c static c89


【解决方案1】:

您可以从静态数据构建链表。在 ANSI C89(又名 ISO C90)中,它可能如下所示:

struct node
{
 int data;
 struct node *next;
};

struct node nodes[] = { { 42, &nodes[1] }, { 137, 0 } };
struct node *list = nodes;

在 ISO C99(2000 年被 ANSI 采用)中,您还可以使用复合文字,例如

struct node *list = &(struct node){ 42, &(struct node){ 137, 0 } };

将静态分配的节点与动态分配的节点混合是有问题的,因为释放前者会导致未定义的行为,因此有必要跟踪哪些节点属于哪个组。

【讨论】:

  • 这是个狡猾的主意。对于自动注册场景,我该如何做?就像,在 foo.c 中我有代码要添加到 bar.h 中声明的列表中,而在 baz.c 中我也添加到列表中,等等。基本上,我想分散“列表添加”和所有数据将是静态的。
【解决方案2】:

好吧,你可以在 main 方法中初始化 placeholder :-)

【讨论】:

  • 你为什么需要这个宏?
【解决方案3】:

不,没有这样的事情。您可以使用静态数据初始化静态变量。添加到列表中不是“静态的”。 我相信大多数人所做的是编写一个预处理器来扫描源文件,在“全局列表”中找到你想要的东西,然后生成一个带有适当数据的 .c 文件(例如 NULL 终止的静态初始化表) .

【讨论】:

  • 您无法在其他文件中执行此操作。至少不在 .o 文件中,因为无法“初始化”列表(或表)。而且我认为没有足够的宏魔法来通过 .h 文件对其进行初始化。
【解决方案4】:

正如您所注意到的,C 没有这种能力。如果您不能在 C 之外执行此操作(通过生成 C 代码),那么另一种方法是为每个需要它的模块创建一个 initialize() 函数,并确保在适当的时间调用这些函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    相关资源
    最近更新 更多