Я обнаружил, что компилятор 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? И как можно объяснить наблюдаемое поведение?