gpt4 book ai didi

c - 使用 C99 之前的编译器构建 C 迭代器宏

转载 作者:太空狗 更新时间:2023-10-29 16:07:33 24 4
gpt4 key购买 nike

我的代码必须使用 C99 之前的编译器进行编译(我们正在努力更新,但这是一项艰巨的任务),它正在调用一个专为 C99 设计的实用程序库。特别是,这些实用程序定义了一个 hashmap 类型并提供了一个宏来迭代它,类似于以下内容:

#define MAP_FOREACH(key, val, map) \
for (struct _map_iterator iter __attribute__((cleanup(_map_iter_cleanup))); \
(key) = iter->pair->key, \
(value) = iter->pair->value; \
iter = iter->get_next_cb())

实际代码还有更多内容(确保迭代器名称唯一的功能等),但这涵盖了我的问题的核心,即 1999 年之前的 C 版本不支持初始化变量在一个for循环中。现在,这里明显的解决方法是将初始化移到循环之外,代码如下所示:

// Doesn't work
#define MAP_FOREACH(key, val, map) \
struct _map_iterator iter __attribute__((cleanup(_map_iter_cleanup)));
for (; \
(key) = iter->pair->key, \
(value) = iter->pair->value; \
iter = iter->get_next_cb())

问题是 __attribute__((cleanup(_map_iter_cleanup))) 位。根据GCC documentation ,定义附加到变量的清理代码,当变量超出范围时运行。因为我们将迭代器声明移到了 for 循环之外,它的作用域发生了变化,清理代码在别处运行。不幸的是,库的其他部分依赖于立即清理迭代器 - map 会跟踪已启动的迭代器数量,如果迭代器在它们全部消失之前被销毁,则会抛出错误。

几天来,我一直在尝试并未能想出一个干净的方法来解决这个问题,但我做空了。我真的不想在 C99 之前的代码中重新实现宏加清理,但是到处都在使用这个库,并且更改 API 以包含迭代后清理调用会很痛苦,而不是提到不雅。

有没有人以前遇到过这种事情并且知道解决办法?

编辑:我们使用带有 -std=c89 选项的 GCC 4.2.2

最佳答案

我不完全了解 C99 之前的标准缺少的功能,但我认为您可以像下面这样:

#define MAP_FOREACH(key, val, map) \
{
struct _map_iterator iter __attribute__((cleanup(_map_iter_cleanup)));
for (; \
(key) = iter->pair->key, \
(value) = iter->pair->value; \
iter = iter->get_next_cb())

然后无论您在哪里使用它,都必须在循环后附加一个额外的右大括号 }

关于c - 使用 C99 之前的编译器构建 C 迭代器宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22261441/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com