Ответ 1
В соответствии с 16.3.4 стандарта ISO/IEC 14882: 2003 (С++ Stardard) макрораспределение выполняется следующим образом:
- Вызов макроса заменяется списком замены макроса (тело), где каждое имя параметра (если оно не зависит от # или ##) заменяется полным расширением макроса соответствующего аргумента, указанного в вызове макроса.
- Результат этапа 1 повторно сканируется. Если в нем больше макросов (кроме тех, которые уже были расширены с учетом рассматриваемого текста), они разворачиваются в соответствии с той же процедурой рекурсивно.
Последовательность шагов для указанного вами кода:
-
BAR(BAZ)
-
FOO(3,7,1)
-
((3)*(7)*(1))
Итак, GCC прав, а VC - нет. Но ошибка, о которой жалуется VC, заключается в том, что FOO
имеет 3 аргумента, а BAR
указывает только 2 из них. VC, по-видимому, пытается поймать ошибки как можно скорее и немного заходит в нее.