Разница между gcc и препроцессором Microsoft

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

17
задан Brian Tompsett - 汤莱恩 17 April 2016 в 12:27
поделиться