В качестве возможного решения вашей проблемы: «напишите макрос, а затем отбросьте его, заменив эквивалентной функцией», вы можете использовать прототипы функционально-подобных макросов.Они имеют некоторые ограничения и должны использоваться с некоторой осторожностью.Но они работают почти так же, как функции.
#define xxPseudoPrototype(RETTYPE, MACRODATA, ARGS) typedef struct { RETTYPE xxmacro__ret__; ARGS } MACRODATA
xxPseudoPrototype(float, xxSUM_data, int x; float y; );
xxSUM_data xxsum;
#define SUM_intfloat(X, Y) ( xxsum = (xxSUM_data){ .x = (X), .y = (Y) }, \
xxsum.xxmacro__ret__ = xxsum.x + xxsum.y, \
xxsum.xxmacro__ret__)
Я объяснил детали здесь (в основном, раздел 4, для функционально-подобных макросов):
Функции подделки макросов
- 1-я строка определяет макрос, который можно использовать для объявления псевдопрототипов для макросов.
- Во второй строке используется этот макрос, предоставляющий такой псевдопрототип .Он определяет «формальные» параметры нужных типов.По порядку он содержит тип возврата, требуемый для макроса, имя структуры, в которой будут храниться параметры макроса, и, наконец, параметры (с типами!) Макроса.Я предпочитаю называть их псевдопараметрами .
- 3-я строка является обязательным утверждением, которое делает «реальными» псевдопараметры .Он объявляет структуру, которую необходимо написать.Он определяет структуру, содержащую «реальную» версию псевдопараметров .
- Наконец, сам макрос определяется как цепочка списков выражений, разделенных запятыми.Первый операнд используется для «загрузки» аргументов макроса в «реальные» типизированные параметры.Последний операнд - это «возвращаемое значение», которое также имеет требуемый тип.
Обратите внимание, что компилятор выполняет правильную и прозрачную диагностику типов.
(Однако необходимо иметь некоторыепозаботьтесь об этих конструкциях, как объяснено в ссылке).
Теперь, если вы можете собрать все предложения вашего макроса в виде цепочки вызовов функций, разделенных запятыми, то вы можете получить подобный функции макрос,по вашему желанию.
Более того, вы можете легко преобразовать его в реальную функцию, поскольку список параметров уже определен.Проверка типов уже выполнена, поэтому все будет работать нормально.В приведенном выше примере вы должны заменить все строки (кроме первой) следующими:
#define xxPseudoPrototype(RETTYPE, MACRODATA, ARGS) typedef struct { RETTYPE xxmacro__ret__; ARGS } MACRODATA
float SUM_intfloat(int x, float y) { /* (1) */
xxPseudoPrototype(float, xxSUM_data, int x; float y; ); /* (2) */
xxSUM_data xxsum; /* (2) */
return /* (3) */
( xxsum = (xxSUM_data){ .x = x, .y = y }, /* (4) (5) (6) */
xxsum.xxmacro__ret__ = xxsum.x + xxsum.y, /* (5) (6) */
xxsum.xxmacro__ret__) /* (6) */
; /* (7) */
} /* (8) */
Замена будет выполняться систематической процедурой:
(1) Макросзаголовок превратился в заголовок функции.Точки с запятой (;) заменяются запятыми (,).
(2) Строки объявления перемещаются внутри тела функции.
(3) Добавлено слово "return".
(4) Макроаргументы X,Y, заменяются параметрами функции x, y.
(5) Все конечные "\" удаляются.
(6) Все вычисления промежуточного выражения и вызовы функций остаются без изменений.
(7) Добавлена точка с запятой.
(8) Корпус функции закрытия.
Проблема: Хотя этот подход решает ваши потребности, обратите внимание, что функция продублировала свой список параметров.Это не хорошо: псевдопрототипы и дубликаты должны быть удалены:
float SUM_intfloat(int x, float y) {
return
( x + y )
;
}