gpt4 book ai didi

c - 用嵌套函数为 Clang 重写 GCC 清理宏?

转载 作者:太空狗 更新时间:2023-10-29 15:00:31 24 4
gpt4 key购买 nike

我正在尝试解决第三方库中的问题。问题是该库使用隐藏在宏中的 GCC 嵌套函数,而 Clang 不支持嵌套函数并且没有计划这样做(参见 Clang Bug 6378 - error: illegal storage class on function)。

这是我和 Clang 的痛点所在的宏:

#define RAII_VAR(vartype, varname, initval, dtor) \
/* Prototype needed due to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36774 */ \
auto void _dtor_ ## varname (vartype * v); \
void _dtor_ ## varname (vartype * v) { dtor(*v); } \
vartype varname __attribute__((cleanup(_dtor_ ## varname))) = (initval)

下面是它的使用方式(来自代码注释):

 * void do_stuff(const char *name)
* {
* RAII_VAR(struct mything *, thing, find_mything(name), ao2_cleanup);
* if (!thing) {
* return;
* }
* if (error) {
* return;
* }
* do_stuff_with_thing(thing);
* }

Clang User Manua l 声明使用 C++ 和 lambda 函数进行模拟。我不确定这是最好的策略,C 项目可能不会接受 C++ 补丁(他们可能会先给我涂上 tar 和羽毛)。

有没有办法重写宏,使其 (1) 更适应 Clang,并且 (2) 保留原始函数语义?

最佳答案

Clang 不支持 GCC 嵌套函数,但它支持 Objective C-style "blocks" ,即使在 C 模式下:

void f(void * d) {
void (^g)(void *) = ^(void * d){ };
g(d);
}

您需要使用 clang 命令而不是 gcc 调用它,并且还(?)将 -fblocks -lBlocksRuntime 传递给编译器.

您不能直接将 block 用作 cleanup 值,因为它必须是函数名称,因此(从 here 窃取想法)您需要添加一个间接层。定义一个函数来清理无效 block ,并使您的 RAII 变量成为您要在作用域末尾运行的 block :

typedef void (^cleanup_block)(void);
static inline void do_cleanup(cleanup_block * b) { (*b)(); }

void do_stuff(const char *name) {
cleanup_block __attribute__((cleanup(do_cleanup))) __b = ^{ };
}

因为 block 形成了闭包,所以您可以将对变量的操作直接放在那个 block 内进行清理...

void do_stuff(const char *name) {
struct mything * thing;
cleanup_block __attribute__((cleanup(do_cleanup))) __b = ^{ ao2_cleanup(thing); };
}

...并且它应该像以前一样在作用域的末尾运行,由 block 上的清理调用。重新排列宏并添加一个 __LINE__ 使其适用于多个声明:

#define CAT(A, B) CAT_(A, B)
#define CAT_(A, B) A##B

#define RAII_VAR(vartype, varname, initval, dtor) \
vartype varname = (initval); \
cleanup_block __attribute__((cleanup(do_cleanup))) CAT(__b_, __LINE__) = ^{ dtor(varname); };

void do_stuff(const char *name) {
RAII_VAR(struct mything *, thing, NULL, ao2_cleanup);
...

无论如何,类似的东西。

关于c - 用嵌套函数为 Clang 重写 GCC 清理宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24959440/

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