This answer is for C, it's similar in C++.
The example is literally the same as in C11 standard 6.4.9p3:
#define glue(x,y) x##y
glue(/,/) k(); // syntax error, not comment
The error you are seeing:
error: pasting "/" and "/" does not give a valid preprocessing token
comes from that the result of ##
needs to be preprocessing tokens. In short, a preprocessing token are identifiers, preprocessing numbers, string literals, punctuators, and other. (See also gcc docs on tokenization). The resulting //
string is not a preprocessing token, so the result of ##
here would not be a preprocessing token. The C standard 6.10.3.3p3 states that if a result of ##
"is not a valid preprocessing token, the behavior is undefined". The compiler you are using chooses to issue an error in such case. It will not work the same way as the following do not work:
concatenate(:, b) // error, `:b` is not a preprocessing token
concatenate(%, b) // error, `%b` is not a preprocessing token
// etc.
Maybe for example from the other side, for example %=
is a valid token, a punctuator. The following are ok:
concatenate(%, =)
concatenate(/, =)
concatenate(a /, = b)
concatenate(<, :)
Anyway, even if //
would be a valid preprocessing, comments are substituted for a single space in translation phase 3, while the preprocessor is executed in translation phase 4 after comments are removed, see C11 translation phases. So, even if it would result in //
token, it would be invalid, as it doesn't mean anything in C (except comments).