2015-07-08 5 views
3

это можно назвать макрос внутри макроса таким образом:Как вызвать макрос внутри макроса?

#include <stdio.h> 
#define AA(a1, a2) a1, 3, 5, a2 
#define BB(x, y1, y2, y3, y4) { printf("%d %d %d %d %d\n",x, y1, y2, y3, y4); } 

int main() 
{ 
    int n = 21, k= 11; 
    BB(31, AA(n,k)); 
} 

этот код возвращает ошибку followinf в сборнике:

test_macro.c: В функции «главный»:
test_macro.c: 9: 18: erreur: macro «BB» requiert 5 аргументов, mais seulement 2 ont été passés
test_macro.c: 9: 4: erreur: 'BB' uneclared (первое использование в этой функции)
test_macro .c: 9: 4: примечание: каждый необъявленный идентификатор tifier сообщается только один раз для каждой функции появляется в

+0

Вы действительно не хотите окончания '}'? –

+0

Что происходит, когда вы пытаетесь? – dbush

+0

Опустите точку с запятой после макроса, или - лучше - если вы используете gcc, скопируйте весь макрос тела (нестандартный), чтобы сделать это выражение. – Olaf

ответ

5

То, что вы, вероятно, хотите, чтобы предоставить дополнительные аргументы BB путем расширения AA(n,k). Как указано Sourav Ghosh, в вашей программе AA(n,k) расширяется после передачи в BB в качестве единственного аргумента. Чтобы его расширить, вы можете использовать еще один макроуровень и определить свою программу как:

#define AA(a1, a2) a1, 3, 5, a2 
#define BB(x, y1, y2, y3, y4) { printf("%d %d %d %d %d\n",x, y1, y2, y3, y4); } 
#define BBB(a,b) BB(a,b) 

int main() 
{ 
    int n = 21, k= 11; 
    BBB(31, AA(n,k)); 
} 
3

В вашем коде, когда следующая строка встречается, на стадии предварительной обработки,

BB(31, AA(n,k)); 

согласно правилу Макроподстановка, во-первых, BB будет расширен (заменен), как указано в списке замещения , тогда в списке замещения, если возможна какая-либо другая замена MACRO (здесь AA), которая будет следующей.

Проблема возникает. MACRO определение BB принимает 5 аргументов, но вы проходите всего 2, потому что расширение AA еще не состоялось.

Связанные с C11, глава §6.10.3, Macro замена (курсив мой)

предварительной обработки директивы формы

# define identifier replacement-list new-line 

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

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