Как получить определение макроса в виде строкового литерала?
Скажите в заголовке, который я не хочу читать сам, но который я действительно включаю, у меня есть
#define A B
#define B C
Теперь
#define STR(name) # name
определяет макрос, который дает мне имя любого макроса в виде строки, а
#define EXP_STR(name) STR(name)
определяет макрос, который дает мне полное расширение любого макроса в виде строки. Так
cout << STR(A) << EXP_STR(A) << endl;
напечатает AC
.
Есть ли способ получить "B"
из A
с помощью некоторых макросов?
Ответы
Ответ 1
Поскольку вы можете написать
#define B C
#define A B
#define STR(name) # name
#define EXP_STR(name) STR(name)
и
cout << STR(A) << EXP_STR(A) << endl;
будет выводить exaccty одинаково, это означает, что это невозможно.
Когда вы это сделаете
#define A B
а затем
#define B C
теперь это означает, что A
будет заменено на C
, а не B
, поэтому не будет никакого способа сделать это, потому что когда строка cout
будет достигнута, препроцессор уже заменил A
на C
.
Итак, короткий ответ: это невозможно, потому что препроцессор заменил бы A
на C
перед компиляцией файла.
Ответ 2
Да, это возможно. Вам просто нужно использовать пару читов.
-
#undef B
до #define EXP_STR
- Используйте еще несколько уровней косвенности
Например:
#define A B
#define B C
#define _TEMP_VAR B // so that it can be redefined later
#undef B // so that EXP_STR(A) will return "B"
#define EXP_STR__(x) (x)
#define EXP_STR_(x) EXP_STR__(#x)
#define EXP_STR(x) EXP_STR_(x)
#define STR(x) # x
#define B _TEMP_VAR // now you can still access A normally, defined to B (defined to C)
Пробная программа для подтверждения:
#include <stdio.h>
int main(void)
{
printf( "EXP_STR(A) = %s\n", EXP_STR(A) );
printf( "STR(A) = %s\n", STR(A) );
}
Выход:
EXP_STR(A) = B
STR(A) = A