C Программирование: препроцессор, macros в качестве токенов

Я пытаюсь сделать что-то концептуально похожее на это, но, похоже, не может заставить его работать (ошибка показана в конце) какие-либо идеи?

#include  int main( int argc , char const *argv[] ) { int abc_def_ghi = 42; #define SUFFIX ghi #define VAR(prefix) prefix##_def_##SUFFIX printf( "%d\n" , VAR(abc) ); return 0; } // untitled:8: error: 'abc_def_SUFFIX' undeclared (first use in this function) 

Вам просто нужно дополнительное косвенное отношение:

 #include  int main( int argc , char const *argv[] ) { int abc_def_ghi = 42; #define SUFFIX ghi #define VAR3(prefix, suffix) prefix##_def_##suffix #define VAR2(prefix, suffix) VAR3(prefix, suffix) #define VAR(prefix) VAR2(prefix, SUFFIX) printf( "%d\n" , VAR(abc) ); return 0; } 

Хотя это выглядит излишним, это не так.

Обычная идиома для правильного использования операторов строковой привязки ( # ) или маркировки ( ## ) предварительной обработки состоит в использовании второго уровня косвенности. ( Каковы приложения оператора ## препроцессора и gotchas для рассмотрения? ).

 #define STRINGIFY2( x) #x #define STRINGIFY(x) STRINGIFY2(x) #define PASTE2( a, b) a##b #define PASTE( a, b) PASTE2( a, b) 

Затем:

 int main( int argc , char const *argv[] ) { int abc_def_ghi = 42; #define SUFFIX ghi #define VAR(prefix) PASTE( prefix, PASTE( _def_, SUFFIX)) printf( "%d\n" , VAR(abc) ); return 0; } 

Должны дать вам результаты, которые вы ищете.

В основном, происходит то, что обработка операторов # и ## происходит до замены макроса. Затем происходит другой раунд замены макросов. Поэтому, если вы хотите, чтобы macros использовались вместе с этими операциями, вы должны использовать 1-й уровень, который просто заменяет – в противном случае сначала происходит строковое кодирование или вставка, а macros больше не являются макросами – они все равно 1-го раунда строгание / вставка.

Чтобы выразить это более прямо – первый уровень макроса позволяет заменить макропараметры, затем второй уровень замены макросов выполняет операцию подкрепления / маркера.

Это работает с достаточными уровнями косвенности. В то время как другой ответ достаточно адекватен, я хочу предложить этот fragment кода в качестве демонстрации:

 #define SUFFIX ghi #define VAR1(prefix) prefix##_def_##SUFFIX VAR1(abc) #define VAR2_(prefix, sfx) prefix##_def_##sfx #define VAR2(prefix) VAR2_(prefix,SUFFIX) VAR2(abc) #define VAR3_(prefix, sfx) prefix##_def_##sfx #define VAR3x(prefix,sfx) VAR3_(prefix,sfx) #define VAR3(prefix) VAR3x(prefix,SUFFIX) VAR3(abc) 

Сохраните это текстовый файл, xc и только предварительно обработайте его.

 gcc -E xc 

Наблюдайте и обдумывайте. Я не совсем понимаю это сам. Просто потратьте два часа, пытаясь получить макрос, используя stringify для работы. Интересно видеть, что иногда требуется двойная косвенность.