Есть набор структур с именами, различающимися индексом, и стоит задача выбрать одну конкретную с предопределённым индексом (т.е. индекс определён в виде подставляемого значения макроса)
Например, нужно выбрать из множества такую структуру:
struct FOO_5i {
int foo;
};
Рабочий вариант:
#define INDEX 5
#define GENERATE_NAME(prefix, value, trailing) prefix##value##trailing
#define FOO_STRUCT_INDEX(val) GENERATE_NAME(FOO_, val, i)
#define FOO_STRUCT FOO_STRUCT_INDEX(INDEX)
FOO_STRUCT test; // test имеет тип FOO_5i
А, скажем, такой вариант не работает, подставляя не значение INDEX, а генерируя "FOO_INDEXi"
#define INDEX 5
#define GENERATE_NAME(prefix, value, trailing) prefix##value##trailing
#define FOO_STRUCT GENERATE_NAME(FOO_, INDEX, i)
FOO_STRUCT test; // test имеет тип FOO_INDEXi, такого типа не существует
второй нерабочий вариант:
#define INDEX 5
#define GENERATE_FOO_STRUCT_NAME(value) FOO_##value##i
#define FOO_STRUCT GENERATE_FOO_STRUCT_NAME(INDEX)
FOO_STRUCT test; // test имеет тип FOO_INDEXi, такого типа не существует
Я примерно понимаю, что происходит: судя по всему, при передаче макроса в качестве параметра другому макросу препроцессор выполняет подстановку макроса-параметра только тогда, когда разворачивает параметризованный макрос - в противном случае выполняет тупую подстановку, и конкатенация съедает макрос. Т.е. подстановка происходила бы в макросе GENERATE_NAME, но конкатенация "растворяет" макрос INDEX. Скажем, такой код
#define INDEX 5
#define GENERATE_FOO_STRUCT(value) struct FOO_##value##i { static const int foo = value; }
#define FOO_STRUCT GENERATE_FOO_STRUCT(INDEX)
FOO_STRUCT test;
порождает структуру FOO_INDEXi со статической константой, равной 5.
Суть происходящего вкратце ясна - вопрос, насколько стандартно такое поведение. В VS2008 и MinGW поведение препроцессора одинаковое