The issue is with the way tokenization works. The gcc documentation has a page about tokenization and concatenation from which I glean the following:
The preprocessor separates the source code into tokens which are roughly equivalent to the C compiler tokens (e.g. literals, identifiers or operators). These tokens can be combined with the ##
operator. The result of the concatenation must in turn be a token (for example, an identifier-shaped thing, a number, an operator), which is not the case here, which is why the compiler complains.
The key is that the character sequence [0]
is separated into the three-token sequence[
, 0
, ]
. The concatenation operator uses only [
as its right hand side operator; the result x[
is not a token.
As a counter-example, the following works:
#define MAKE_ASSIGN_OP(x) x##=int main() { int x=1; return x MAKE_ASSIGN_OP(+) 1; }
Both +
and =
as well as their concatenation +=
are valid tokens.
As an example