2016-02-06 6 views
1

Я хотел бы иметь макрос, который печатает его собственное имя (между прочим), но я не могу найти способ расширения макросов ' имя в самом макросе. В принципе, я хочу эквивалент __FUNCTION__ для имени макроса.Препроцессор C: есть ли способ расширить имя макроса внутри себя

Например:

#define F(a, b, c) do { \ 
    printf("%s: %s,%s,%s\n", __MACRO__, #a, #b, #c); \ 
    c = a+b; b=a; \ 
} while(0) 

F(x,y,z); 

Я хотел бы, чтобы напечатать "F: х, у, г" при вызове.


Это действительно проблема XY.

Вот что я пытаюсь сделать: Мягкие ссылки символов из библиотеки с помощью dlopen и dlsyms.

Для этого типичный способ, который я знаю: 1) Включите заголовки из библиотеки. 2) Объявить переменную типа функции, которую вы пытаетесь импортировать. 3) Инициализировать указанную переменную вызовом dlsym 4) Вызывать фактическую функцию через эту переменную вместо прямого вызова символа.

Когда у вас есть такая функция для софт-ссылки, она становится очень повторяющейся, поэтому макрос может помочь.

Для полного примера оперяются того, смотрите здесь: https://github.com/WebKit/webkit/blob/master/Source/WebCore/platform/mac/SoftLinking.h

Проблема в этом примере и других является то, что вам все еще нужно вручную скопировать список параметров для каждой функции, которые вы хотите мягкую ссылку. Я пытаюсь улучшить это и экспериментировал с макро-трюками, одному из которых было бы полезно, чтобы ответить на мой первоначальный вопрос.

-

Помимо моих мягких вопросов увязывания, есть и другие ситуации, когда это может быть полезным. Например, для целей отладки можно распечатать некоторую диагностическую информацию до или после каждого вызова определенных функций. Можно было бы сделать это с помощью переопределения функции имен с помощью макросов:

#define funcA(...) \ 
printf("Before call to %s:%d - %d\n", #funcA, __LINE__, g_count); \ 
funcA(__VA_ARGS__) \ 
printf("After call to %s:%d - %d\n", #funcA, __LINE__, g_count); 

Это работает достаточно хорошо, но если я хочу сделать это для связки функции, я должен скопировать этот макрос и изменить funcA в funcB 4 раза для каждого новый макрос. Я бы предпочел скопировать его и просто изменить имя макросов, не изменяя, что внутри.

я могу оптимизировать выше, определяя внутреннюю р макросъемки, подобный тому, что предложил Basile:

Но это по-прежнему означает, что мне нужно изменить funcA на новое имя функции дважды каждый раз, когда я скопировать макрос для другой функции.

+1

Почему вы хотите сделать код нечитаемым и более сложным для отладки? Почему некоторые люди любят препроцессора. Это место для простых вещей. –

+0

Ну, этот пример слишком прост. В моем фактическом прецеденте «printf» фактически был встроен в другие макросы, такие как «#define P (f, ...) printf («% s% s \ n », f, __VA_ARGS __)' – Droopycom

+0

@EdHeal I Фактически я пытаюсь не копировать пасту в виде кучи раз. – Droopycom

ответ

2

Подробнее о C preprocessor. Прочтите документацию GNU cpp. Обратите внимание на свои способности stringification и concatenation.

Возможно идти через какой-то дополнительный внутренний макрос может помочь вам, так что вы можете иметь открытый макрос как

#define FOO(X,Y,Z) PRIVATE_FOO(FOO,X,Y,Z) 

с другой PRIVATE_FOO макро делать трюки stringification на первом аргументе, может быть

#define PRIVATE_FOO(Mac,X,Y,Z) do { \ 
printf("%s: %s,%s,%s\n", #Mac, #X, #Y, #Z); \ 
Z = X+Y; Y=X; \ 
} while(0) 

Возможно, препроцессор C не подходит для вашей задачи. Вы могли бы сгенерировать некоторый код C каким-либо другим инструментом (возможно, препроцессором GPP или, может быть, простым сценарием awk или python или, возможно, какой-то реальной программой, вам нужно будет изменить процесс сборки, например, ваш Makefile, чтобы справиться с этим). Вы можете настроить компилятор GCC с MELT, если вам это нужно. Поскольку мы не знаем ваших реальных мотивов, мы не можем больше помочь.

Я не могу больше помочь, если вы не мотивируете и не уточняете свой вопрос.

Для устранения проблемы с мягкой связью необходимо просто использовать weak symbols. Вероятно, это не связано с предварительной обработкой С.

+0

Отсутствие слабых символов или слабая связь - это другая проблема, чем мягкая привязка, по крайней мере, на моей платформе (OS X). В частности, при софт-привязке (как я уже описал выше) вам не нужно иметь библиотеку, которую вы мягко связываете во время сборки, в то время как вам все еще нужно ее при слабой связи. – Droopycom

+0

Что касается вашего комментария о внутренних макросах, это действительно то, что я пытаюсь использовать, и именно поэтому я хотел бы получить имя макроса. – Droopycom

Смежные вопросы