LINUX.ORG.RU

Однопроходный препроцессор

 ,


2

2

Препроцессор си является однопроходным, так?

Тогда как он разворачивает перекрещенную конструкцию из ITER1-ITER2-ITER1...?

#define ITERATE(seq) SEQ(ITER1 seq)
#define SEQ(x) SEQ_I(x)
#define SEQ_I(x) x ## _END
#define ITER1(seq) seq ITER2
#define ITER2(seq) seq ITER1
#define ITER1_END
#define ITER2_END

ITERATE((a) (b) (c))

Можете, пожалуйста, рассказать по шагам, почему оно вообще разворачивается?

★★

Последнее исправление: cetjs2 (всего исправлений: 2)
ITERATE((a) (b) (c))
SEQ(ITER1 (a) (b) (c))
SEQ_I(ITER1 (a) (b) (c))
ITER1 (a) (b) (c) ## _END
a ITER2 (b) (c) ## _END
a b ITER1 (c) ## _END
a b c ITER2 ## _END
a b c ITER2_END
a b c
mix_mix ★★★★★
()
Ответ на: комментарий от mix_mix

А, точно. Спасибо. Мне надо больше спать.

sambist ★★
() автор топика

Я бы такое на баше или питоне пред-намолотил... :)

I-Love-Microsoft ★★★★★
()

По шагам. Сначала

prev-code <CPP здесь> ITERATE((a) (b) (c)) next-code

Дальше CPP проглатывает следующий токен:

prev-code <CPP разворачивает ITERATE((a) (b) (c))> next-code

и выдает результат

prev-code <CPP здесь> SEQ(ITER1(a) (b) (c)) next-code

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

Далее CPP снова проглатывает первый токен на входе

prev-code <CPP разворачивает SEQ(<CPP разворачивает ITER1(a)> (b) (c))> next-code
prev-code <CPP разворачивает SEQ(a <CPP разворачивает ITER2(b)> (c))> next-code
prev-code <CPP разворачивает SEQ(a b <CPP разворачивает ITER1(c)>)> next-code
prev-code <CPP разворачивает SEQ(a b c ITER2)> next-code
prev-code <CPP здесь> SEQ_I(a b c ITER2) next-code
prev-code <CPP разворачивает SEQ_I(a b c ITER2)> next-code
prev-code <CPP здесь> a b c ITER2_END next-code

kim-roader ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.