Поведение препроцессора языка Си - PullRequest
2 голосов
/ 29 мая 2010

В языке C существуют различные типы макросов, одним из которых является вложенный макрос.

Рассматривая программу со следующим макросом

#define HYPE(x,y) (SQUR(x)+SQUR(y))
#define SQUR(x)   (x*x)

Используя это, мы можем успешно скомпилировать, чтобы получить результат.

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

Ответы [ 2 ]

1 голос
/ 29 мая 2010

замена происходит, когда фактически используется «HYPE». он не раскрывается при выполнении оператора #define.

например:

1 #define FOO 1
2
3 void foo() {
4    printf("%d\n", FOO);
5 }

поэтому замена происходит в строке 5, а не в строке 1. следовательно, ответ на ваш вопрос: один раз.

0 голосов
/ 29 мая 2010

A #define вызов макроса расширяется до тех пор, пока не останется больше терминов для расширения, за исключением того, что он не повторяется. Например:

#define TIMES        *
#define factorial(n) ((n) == 0 ? 1 : (n) TIMES factorial((n)-1))
    // Doesn't actually work, don't use.

Предположим, вы говорите factorial(2). Это расширится до ((2) == 0 ? 1 : (2) * factorial((2)-1)). Обратите внимание, что factorial расширяется, затем TIMES также расширяется, но factorial впоследствии не расширяется, поскольку это будет рекурсия.

Тем не менее, обратите внимание, что вложение (возможно, другой тип «рекурсии») фактически многократно расширяется в одном и том же выражении:

#define ADD(a,b)     ((a)+(b))
....
ADD(ADD(1,2),ADD(3,4)) // expands to ((((1)+(2)))+(((3)+(4))))
...