[ACCEPTED]-How can I generate unique values in the C preprocessor?-c-preprocessor

Accepted answer
Score: 21

If you're using GCC or MSVC, there is __COUNTER__.

Other 1 than that, you could do something vomit-worthy, like:

#ifndef USED_1
#define USED_1
1
#else
#ifndef USED_2
#define USED_2
2
/* many many more */
#endif
#endif
Score: 18

I use this:

#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;
}

... and get the following:

int main()
{
    int unique_name_8 = 1;
    return 0;
}

0

Score: 16

As others noted, __COUNTER__ is the easy but nonstandard 6 way of doing this.

If you need extra portability, or 5 for other cool preprocessor tricks, the 4 Boost Preprocessor library (which works for C as well as C++) will 3 work. For example, the following header 2 file will output a unique label wherever 1 it's included.

#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)):

Sample:

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;
}

preprocesses to

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;
}
Score: 7

I can't think of a way to automatically 2 generate them but you could pass a parameter 1 to MAKE_LABEL:

#define MAKE_LABEL(n) my_cool_label_##n:

Then...

MAKE_FUNNY_JUMPING_LOOP(
  MAKE_LABEL(0);
  MAKE_LABEL(1);
)
Score: 0

You could do this:

#define MAKE_LABEL() \
do {                 \   
my_cool_label:       \
/* some stuff */;    \
goto my_cool_label;  \
/* other stuff */;   \
} while (0) 

This keeps the scope of 5 the label local, allowing any number of 4 them inside the primary macro.

If you want 3 the labels to be accessed more globally, it's 2 not clear how your macro "MAKE_FUNNY_JUMPING_LOOP" references these 1 labels. Can you explain?

More Related questions