【发布时间】:2012-08-15 22:33:50
【问题描述】:
我正在用 C / Objective-C 开发一个应用程序(请不要使用 C++,我已经有一个解决方案),我遇到了一个有趣的用例。
因为clang不支持嵌套函数,所以我原来的做法不行:
#define CREATE_STATIC_VAR(Type, Name, Dflt) static Type Name; __attribute__((constructor)) void static_ ## Type ## _ ## Name ## _init_var(void) { /* loading code here */ }
这段代码使用 GCC 可以很好地编译,但是由于 clang 不支持嵌套函数,我得到一个编译错误:
预期的';'在声明结束时。
所以,我找到了一个适用于函数内部变量的 Clang 解决方案:
#define CREATE_STATIC_VAR_LOCAL(Type, Name, Dflt) static Type Name; ^{ /* loading code here */ }(); // anonymous block usage
但是,我想知道是否有一种方法可以利用宏连接来选择适合这种情况的连接,例如:
#define CREATE_STATIC_VAR_GLOBAL(Type, Name, Dflt) static Type Name; __attribute__((constructor)) void static_ ## Type ## _ ## Name ## _init_var(void) { /* loading code here */ }
#define CREATE_STATIC_VAR_LOCAL(Type, Name, Dflt) static Type Name; ^{ /* loading code here */ }(); // anonymous block usage
#define SCOPE_CHOOSER LOCAL || GLOBAL
#define CREATE_STATIC_VAR(Type, Name, DFLT) CREATE_STATIC_VAR_ ## SCOPE_CHOOSER(Type, Name, Dflt)
显然,结束的实现不必完全一样,但类似的就足够了。
我曾尝试将__builtin_constant_p 与__func__ 一起使用,但因为__func__ 不是编译时常量,所以这不起作用。
我也尝试过使用__builtin_choose_expr,但这似乎不适用于全局范围。
我在文档中还缺少什么吗?看起来这应该是一件相当容易做到的事情,但我似乎无法弄清楚。
注意:我知道我可以简单地输入 CREATE_STATIC_VAR_GLOBAL 或 CREATE_STATIC_VAR_LOCAL 而不是搞乱宏连接,但这是我试图推动编译器的极限。我也知道我可以使用 C++ 并立即解决这个问题,但这不是我的目标。
【问题讨论】:
-
clang 根本不支持嵌套函数吗?对于 GCC,有
-fnested-functions开关,不是可用于 clang 吗?顺便说一句,为什么在编译时需要这个?检查 func 是否为 NULL 或空字符串可以完成这项工作,不是吗? -
@H2CO3 是的,这是一个宏,用于创建从配置加载的静态变量,它需要在编译时。至于 clang 不支持嵌套函数,请阅读:clang.llvm.org/docs/UsersManual.html#c_unimpl_gcc
-
谢谢,这很有趣(也很抱歉......)
-
顺便说一句,你想用这个来实现什么?你不应该重新设计你的代码而不是 CPP 黑客吗?
标签: scope global-variables clang static-variables nested-function