Этот ответ для C, он аналогичен в C ++.
Пример буквально такой же, как в C11 стандартном 6.4.9p3 :
#define glue(x,y) x##y
glue(/,/) k(); // syntax error, not comment
Ошибка, которую вы видите:
ошибка: вставка "/" и "/" не дает действительный токен предварительной обработки
происходит из-за результата ##
требуется предварительная обработка токенов. Короче говоря, токен предварительной обработки - это идентификаторы, числа предварительной обработки, строковые литералы, знаки препинания и другие. (См. Также g cc документы по токенизации ). Результирующая строка //
не является токеном предварительной обработки, поэтому результат ##
здесь не будет токеном предварительной обработки. Стандарт C 6.10.3.3p3 гласит, что если результат ##
"не является допустимым токеном предварительной обработки, поведение не определено". Компилятор, который вы используете, решает выдать ошибку в таком случае. Он не будет работать так же, как и следующие:
concatenate(:, b) // error, `:b` is not a preprocessing token
concatenate(%, b) // error, `%b` is not a preprocessing token
// etc.
Может быть, например, с другой стороны, например %=
- это действительный токен, пунктуатор . Все в порядке:
concatenate(%, =)
concatenate(/, =)
concatenate(a /, = b)
concatenate(<, :)
В любом случае, даже если //
будет допустимой предварительной обработкой, комментарии заменяются одним пробелом в фазе перевода 3, в то время как препроцессор выполняется в фазе перевода 4 после комментариев удалены, см. C11 фазы перевода . Таким образом, даже если это приведет к //
токену, он будет недействительным, поскольку ничего не значит в C (кроме комментариев).