Если у вас есть
#define CONCAT(x,y) x##y
#define CONCAT2(x,y) CONCAT(x,y)
тогда, когда препроцессор видит
CONCAT(a,CONCAT(b,c))
он знает, что список замены для CONCAT (x, y) равен x ## y, поэтому он собирается заменить x на a и y на CONCAT (б, в) . Вопрос только в том, расширится ли он a и / или CONCAT (b, c) до замены? a не является макросом, поэтому расширение невозможно, и в списке замен x ## y, y предшествует ##, поэтому расширение аргумента CONCAT (b, c) не выполняется. Таким образом, замена выполняется без раскрытия, и список замен становится ## CONCAT (b, c), а затем, прежде чем проверять наличие дополнительных макросов, обрабатывает ## и список замен становится aCONCAT (b, c).
Если препроцессор видит
CONCAT2(a,CONCAT2(b,c))
он знает, что список замены для CONCAT2 (x, y) - это CONCAT (x, y), поэтому он собирается заменить x на a и y с CONCAT2 (b, c) . Вопрос только в том, расширится ли он a и / или CONCAT2 (b, c) до замены? a не является макросом, поэтому расширение невозможно, и в списке замен CONCAT (x, y), y НЕ предшествует # или ## или после него ##, поэтому CONCAT2 (b, c) ПОЛНОСТЬЮ расширен до замены. Так что CONCAT2 (b, c) расширяется до CONCAT (b, c), который расширяется до b ## c, дальнейшее расширение невозможно, поэтому y заменяется на b # #c. Список замены x ## y становится ## b ## c и либо становится ab ## c, а затем abc, либо становится ## bc, а затем abc.
Если препроцессор видит
CONCAT2(a,CONCAT(b,c))
он знает, что список замены для CONCAT2 (x, y) - это CONCAT (x, y), поэтому он собирается заменить x на a и y с CONCAT (b, c) . Вопрос только в том, расширится ли он a и / или CONCAT (b, c) перед заменой? a не является макросом, поэтому расширение невозможно, и в списке замены CONCAT (x, y), y НЕ предшествует # или ## или после него ##, поэтому CONCAT (b, c) ПОЛНОСТЬЮ расширяется ДО замены. Таким образом, CONCAT (b, c) расширяется до b ## c, дальнейшее расширение невозможно, поэтому y заменяется на b ## c, список замены x ## y становится # # b ## c, либо он становится ab ## c и затем abc, либо становится ## bc, а затем abc.
Если препроцессор видит
CONCAT(a,CONCAT2(b,c))
он знает, что список замены для CONCAT (x, y) равен x ## y, поэтому он собирается заменить x на a и y на CONCAT2 (б, в) * 1 087 *. Вопрос только в том, расширится ли он a и / или CONCAT2 (b, c) до замены? a не является макросом, поэтому расширение невозможно, и в списке замен x ## y, y предшествует ##, поэтому расширение аргумента CONCAT2 (b, c) не выполняется. Таким образом, замена выполняется без раскрытия, и список замен становится ## CONCAT2 (b, c), а затем, прежде чем проверять наличие дополнительных макросов, обрабатывает ## и список замен становится aCONCAT2 (b, c).
Возможно, вы думаете, что
#define CONCAT2(x,y) CONCAT(x,y)
означает, что
CONCAT2 (x, y) должен совпадать с CONCAT (x, y)
но помните, что:
Список замены для CONCAT (x, y) - x ## y, и поскольку за x следует ##, а y предшествует ##, когда препроцессор видит экземпляр макроса CONCAT, он будет не расширяйте аргументы, которые соответствуют x или y перед заменой. Однако списком замены для CONCAT2 (x, y) является CONCAT (x, y), и ни x, ни y в замене не предшествуют # или ## или после ##, поэтому, когда препроцессор видит экземпляр макроса CONCAT2 , он расширит все макросы в аргументах ПОЛНОСТЬЮ ПЕРЕД заменой.
Макро раскрытие аргументов (если разрешено) происходит ДО замены.Таким образом, в CONCAT2 (a, CONCAT (b, c)) аргумент CONCAT (b, c) раскрывается ДО замены.Таким образом, мы получаем CONCAT2 (a, b ## c), а не CONCAT (a, CONCAT (b, c)).