我怎样才能在C预处理器中生成唯一的值?
我正在写一堆相关的预处理macros,其中一个生成另一个跳转到的标签。 我以这种方式使用它们:
MAKE_FUNNY_JUMPING_LOOP( MAKE_LABEL(); MAKE_LABEL(); )
我需要一些方法来生成独特的标签,每个内部MAKE_LABEL
调用一个预处理器。 我尝试过使用__LINE__
,但是由于我在另一个macros里面调用了MAKE_LABEL
,它们都有相同的行并且标签发生了碰撞。
我想要扩展到这样的东西:
MAKE_FUNNY_JUMPING_LOOP( my_cool_label_1: // from first inner macro ... my_cool_label_2: // from second inner macro ... )
有预处理器生成散列或自动递增整数的方法吗?
正如其他人所指出的, __COUNTER__
是这样做的简单但不标准的方法。
如果你需要额外的可移植性,或者其他很酷的预处理器技巧, Boost预处理器库 (适用于C以及C ++)将会工作。 例如,下面的头文件将输出一个唯一的标签,无论它包含在哪里。
#include <boost/preprocessor/arithmetic/inc.hpp> #include <boost/preprocessor/slot/slot.hpp> #if !defined(UNIQUE_LABEL) #define UNIQUE_LABEL #define BOOST_PP_VALUE 1 #include BOOST_PP_ASSIGN_SLOT(1) #undef BOOST_PP_VALUE #else #define BOOST_PP_VALUE BOOST_PP_INC(BOOST_PP_SLOT(1)) #include BOOST_PP_ASSIGN_SLOT(1) #undef BOOST_PP_VALUE #endif BOOST_PP_CAT(my_cool_label_, BOOST_PP_SLOT(1)):
样品:
int main(int argc, char *argv[]) { #include "unique_label.h" printf("%x\n", 1234); #include "unique_label.h" printf("%x\n", 1234); #include "unique_label.h" return 0; }
预处理
int main(int argc, char *argv[]) { my_cool_label_1: printf("%x\n", 1234); my_cool_label_2: printf("%x\n", 1234); my_cool_label_3: return 0; }
如果您使用GCC或MSVC,则有__COUNTER__
。
除此之外,你可以做一些呕吐物,比如:
#ifndef USED_1 #define USED_1 1 #else #ifndef USED_2 #define USED_2 2 /* many many more */ #endif #endif
我使用这个:
#define MERGE_(a,b) a##b #define LABEL_(a) MERGE_(unique_name_, a) #define UNIQUE_NAME LABEL_(__LINE__) int main() { int UNIQUE_NAME = 1; return 0; }
…并得到以下内容:
int main() { int unique_name_8 = 1; return 0; }
我想不出一种方法来自动生成它们,但是你可以传递一个参数给MAKE_LABEL:
#define MAKE_LABEL(n) my_cool_label_##n:
然后…
MAKE_FUNNY_JUMPING_LOOP( MAKE_LABEL(0); MAKE_LABEL(1); )
你可以这样做:
#define MAKE_LABEL() \ do { \ my_cool_label: \ /* some stuff */; \ goto my_cool_label; \ /* other stuff */; \ } while (0)
这将标签的范围保持在本地,允许其中的任何数量的主macros。
如果你想让标签更全面地被访问,那么你的macros"MAKE_FUNNY_JUMPING_LOOP"
如何引用这些标签并不清楚。 你可以解释吗?
标准预处理器看起来不太可能,尽pipe可以通过将参数放在MAKE_LABEL或MAKE_FUNNY_JUMPING_LOOP中来伪造它,并使用标记粘贴来创build标签。
没有什么能够阻止你制作自己的预处理脚本,为你自动增加。 但是,在这种情况下,它不会是一个标准的C / C ++文件。
可用的命令列表: http : //www.cppreference.com/wiki/preprocessor/start