Обычная идиома для правильного использования операторов предварительной обработки строкового преобразования (#
) или вставки токена (##
) заключается в использовании второго уровня косвенности. (Какие применения оператора препроцессора ## и какие ошибки следует учитывать?).
#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;
}
Должен дать вам результаты, которые вы ищете.
По сути, происходит то, что обработка операторов #
и ##
происходит до замены макроса. Затем происходит еще один раунд замены макроса. Поэтому, если вы хотите, чтобы макросы использовались вместе с этими операциями, вы должны использовать 1-й уровень, который просто выполняет замену - в противном случае сначала выполняется преобразование или вставка, и макросы больше не являются макросами - они соответствуют 1-му раунду нанизывание / оклейка производит.
Говоря более прямо - первый уровень макроса позволяет заменять параметры макроса, затем второй уровень замены макроса выполняет операцию строкового преобразования / вставки токена.
person
Michael Burr
schedule
20.11.2009
const argv
? Впервые вижу такое! Идея кажется хорошей, но я не уверен, что она мне нравится: она делаетmain
несоответствующим и мешает мне делать то, чего я никогда не делал;) - person pmg   schedule 20.11.2009argv
можно объявить как нечто эквивалентноеchar* argv[]
(C99 5.1.2.2.1), и добавлениеconst
не меняет ничего, кроме того, чтоmain()
может с ним делать (без приведения). Помните, что указатель на неконстантный можно без проблем преобразовать в указатель на константу - вплоть до того факта, что значения этих указателей будут сравниваться равными (6.3.2.3/2). - person Michael Burr   schedule 20.11.2009const
), что сделало бы его несоответствующим. Мне это начинает нравиться! - person pmg   schedule 20.11.2009