, почему один из следующих макросов препроцессора не работает, а другой -
Хотя препроцессор будет расширять большинство других макросов, возникающих в результате текущего расширения, он будет выполнять толькоодин шаг расширения.Таким образом, ASTRINGZ(__FILE__)
не будет расширен до полного преобразования в TODO
.
. У вас есть несколько вариантов решения этой проблемы, самый простой - полагаться на факт __FILE__
уже является строковым литералом.
#define msg(s) TODO( s " - @ - " __FILE__)
Но если вы хотите поэкспериментировать с расширением макроса, вы можете попробовать метод отсрочки.Это задержит момент, когда TODO
фактически расширится сам, и даст время аргументам быть развернутыми самим.
#define EMPTY()
#define DEFER(m) m EMPTY EMPTY()()
#define msg(s) DEFER(TODO)( s " - @ - " ASTRINGZ(__FILE__))
Вышеприведенное делает ( s " - @ - " ASTRINGZ(__FILE__))
не быть аргументами для макроса, поэтому ASTRINGZ
будет расширен.Однако DEFER(TODO)
- это макрос, поэтому он будет расширен до TODO EMPTY EMPTY()()
.Потребуется еще два цикла расширения (каждый EMPTY()
для TODO (...)
, который будет возвращен препроцессору. В этот момент все должно быть должным образом расширено.
В чем разница между #pragma и_Pragma
_Pragma
- это еще один стандартный способ предоставления директивы прагмы, специфичной для компилятора. Разница в том, что _Pragma
может быть результатом раскрытия макроса, а #pragma
- директивой, а может и нет.
почему мы обертываем STRINGZ ASTRINGZ?
Это еще один метод отсрочки.