I was surprised to find that
#define A(x) #x A(\n)
expands to "\n" and not "\\n". I got curious and tried
#define A(x) B(x) #define B(x) #x A(A(A(A())))
which, as it turns out, expands to
"\"\\\"\\\\\\\"\\\\\\\"\\\"\""
Note that there are (2N−1) backslashes before a quotes at depth N,
so each level of nesting roughly doubles the output size. That's interesting.
I then timed both gcc and Clang against this cursed construction (N is the number of A's):
N gcc -E clang -E ---- ------------- -------------- 16 5.8 ms 36.2 ms 17 6.3 ms 108.4 ms 18 6.8 ms 399.8 ms 19 8.3 ms 1.558 s 20 10.6 ms 6.512 s 21 14.4 ms 27.693 s 22 18.9 ms 115.347 s 23 30.8 ms 24 55.6 ms 25 111.4 ms 26 175.7 ms 27 349.0 ms 28 724.9 ms 29 1.742 s 30 3.651 s 31 8.970 s 32 22.186 s
Clang somehow takes 4x time to generate 2x as much output. Another problem, not shown here, is that gcc only generates about 4 GiB for N=32. I have no idea why this is; all I know is that it differs from the output for N=31, which somehow has the exact same size. Please let me know if you have any insights.