目标
假设您想要以下内容:
STATIC_EXECUTE {
printf("This probably prints first"\n");
}
STATIC_EXECUTE {
printf("But order isn't guaranteed in the language spec, IIRC"\n");
}
int main(int argc, char **argv) {
printf("This definitely prints last. Buh Bye.\n");
}
实施
C++ 版本 - 静态变量 + 构造函数:
// This is some crazy magic that produces __StaticExecute__247
// Vanilla interpolation of __StaticExecute__##__LINE__ would produce __StaticExecute____LINE__
// I still can't figure out why it works, but it has to do with macro resolution ordering
// If you already have Boost, you can omit this part
#define BOOST_PP_CAT(a, b) BOOST_PP_CAT_I(a, b)
#define BOOST_PP_CAT_I(a, b) BOOST_PP_CAT_II(~, a ## b)
#define BOOST_PP_CAT_II(p, res) res
// This avoids repeating the BOOST_PP_CAT 5X
#define STATIC_EXECUTE \
STATIC_EXECUTE_I(BOOST_PP_CAT(__StaticExecute__, __LINE__))
// This is the meat, a static instance of a class whose constructor runs your code
#define STATIC_EXECUTE_I(uniq_name) \
static struct uniq_name { \
uniq_name(); \
} BOOST_PP_CAT(uniq_name, __var); \
uniq_name::uniq_name() // followed by { ... }
C 版本 - 静态变量 + 函数
// ...
// The meat: a static variable initialized from a function call
#define STATIC_EXECUTE_I(uniq_name) \
static void uniq_name (); \
static int BOOST_PP_CAT(uniq_name, __var) = \
(uniq_name(), 0); \
static void uniq_name() // followed by { ... }
注释
恕我直言,C++ 版本稍微优雅一些。理论上,它消耗的空间略少。否则,土豆,po-tat-哦。
警告:我没有在正确的纯 C 编译器上测试“C”版本。手指交叉;如果它不起作用,请发布注释。
警告:编译器的可移植性通常是一件棘手的事情。如果其他编译器存在错误,我不会感到震惊。
BOOST_PP_CAT 代码从boost/preprocessor/cat.hpp 被盗。我简化了实现,在此过程中可能损害了可移植性。如果它不起作用,请尝试原始(更详细的)实现,并在下面发表评论。或者,如果您已经在使用 Boost,则可以使用他们的版本。
如果您想了解 Boost 的魔力,请注意(至少对我而言,并且在这种情况下),以下内容似乎也有效:
#define BOOST_PP_CAT(a, b) BOOST_PP_CAT_I(a, b)
#define BOOST_PP_CAT_I(a, b) a ## b