Ответ 1
Тот, кто застенчив * дал вам зародыш , но только зародыш. Основной метод преобразования значения в строку в предварительном процессоре C действительно осуществляется с помощью оператора "#", но простая транслитерация предлагаемого решения получает ошибку компиляции:
#define TEST_FUNC test_func
#define TEST_FUNC_NAME #TEST_FUNC
#include <stdio.h>
int main(void)
{
puts(TEST_FUNC_NAME);
return(0);
}
Синтаксическая ошибка находится в строке 'puts()' - проблема заключается в "случайном #" в источнике.
В разделе 6.10.3.2 стандарта C "Оператор #" он говорит:
Каждый # токен предварительной обработки в список заметок для функции макрос должен следовать параметр как следующий токен предварительной обработки в список заметок.
Проблема в том, что вы можете преобразовать макросы в строки, но вы не можете преобразовать случайные элементы, которые не являются аргументами макроса.
Итак, для достижения эффекта, которым вы пользуетесь, вам, безусловно, нужно сделать дополнительную работу.
#define FUNCTION_NAME(name) #name
#define TEST_FUNC_NAME FUNCTION_NAME(test_func)
#include <stdio.h>
int main(void)
{
puts(TEST_FUNC_NAME);
return(0);
}
Я не совсем понимаю, как вы планируете использовать макросы, и как вы планируете избегать повторения вообще. Этот более подробный пример может быть более информативным. Использование макроса, эквивалентного STR_VALUE, - это идиома, необходимая для получения желаемого результата.
#define STR_VALUE(arg) #arg
#define FUNCTION_NAME(name) STR_VALUE(name)
#define TEST_FUNC test_func
#define TEST_FUNC_NAME FUNCTION_NAME(TEST_FUNC)
#include <stdio.h>
static void TEST_FUNC(void)
{
printf("In function %s\n", TEST_FUNC_NAME);
}
int main(void)
{
puts(TEST_FUNC_NAME);
TEST_FUNC();
return(0);
}
* В то время, когда этот ответ был впервые написан, shoosh имя "Shy" было как часть имени.