Я обнаружил, что компилятор Microsoft Visual Studio и gcc предварительно обрабатывают следующий небольшой фрагмент по-разному:
# define M3(x, y, z) x + y + z
# define M2(x, y) M3(x, y)
# define P(x, y) {x, y}
# define M(x, y) M2(x, P(x, y))
M(a, b)
'gcc -E' дает следующее:
a + {a + b}
а 'cl/E' выдает предупреждение о отсутствующем аргументе макроса и выводит следующий результат:
a + {a, b} +
Кажется, что запятые, которые поступают из вложенных расширений макросов, не считаются разделителями аргументов. К сожалению, я не нашел описания алгоритма, реализованного в препроцессоре cl, и поэтому я не уверен, что мое предложение верное. Кто-нибудь знает, как работает препроцессор cl и какая разница между его алгоритмом и gcc? И как можно объяснить наблюдаемое поведение?