给出以下源代码:
#include <stddef.h>
#include <sys/types.h>
#include <dirent.h>
static inline void closedirp(DIR **p) {
if (*p)
closedir(*p);
}
#define auto_cleanup(resource) _Generic((resource), \
DIR **: closedirp, \
)(resource)
int main() {
#ifdef GENERIC
__attribute__((cleanup(auto_cleanup))) DIR * t2 = NULL;
t2 = opendir("/tmp");
#else
__attribute__((cleanup(closedirp))) DIR * t1 = NULL;
t1 = opendir("/tmp");
#endif
}
它编译并运行时没有泄漏,没有定义。但是,当定义GENERIC时,编译失败:
$ gcc foo.c -DGENERIC
foo.c: In function ‘main’:
foo.c:16:2: error: cleanup argument not a function
__attribute__((cleanup(auto_cleanup))) DIR * t2 = NULL;
^
这是_Generic毫无意义的使用,但是我想扩展它并处理许多类型的资源来自动清理。
答案 0 :(得分:1)
_Generic
不是函数,而是启动主表达式的关键字。
但是在这里,你似乎更偏向于错误的轨道:auto_cleanup
是一个宏。像宏这样的函数具有如果没有()
之后没有扩展它们的特殊性。所以在这里你只需要为编译的后续阶段保留标识符auto_cleanup
。但是这个标识符并未声明为后续阶段的任何内容。
总结:
_Generic
表达式,并决定采用_Generic
表达式的哪个分支在所有这些中,没有涉及可用于gcc的cleanup
扩展的函数或函数指针。