Из-за порядка расширения.Документация GCC гласит:
Макро-аргументы полностью макроразвертываются перед тем, как их подставить в тело макроса, если они не будут преобразованы в строку или вставлены с другими токенами.После подстановки все тело макроса, включая замещенные аргументы, снова сканируется для раскрытия макросов.В результате аргументы сканируются дважды, чтобы расширить в них вызовы макросов.
Поэтому, если аргумент будет строковым, он не будет расширен в первую очередь.Вы получаете буквальный текст в скобках.Но если он передается другому макросу, он расширяется.Поэтому, если вы хотите расширить его, вам нужно два уровня макросов.
Это сделано потому, что есть случаи, когда вы не хотите расширить аргумент перед строкой, чаще всего этоassert()
макрос.Если вы пишете:
assert(MIN(width, height) >= 240);
, вы хотите, чтобы сообщение было:
Assertion MIN(width, height) >= 240 failed
, а не какой-то безумной вещью, в которую расширяется макрос MIN (в gcc он использует несколько специфичных для gcc расширений идовольно долго IIRC).