A step-by-step C / C++ macro expansion visualizer. Paste in any
#defines and an invocation, and watch each substitution, stringization,
paste, and rescan happen one token at a time.
Live at https://macroscope.orlac.io
Macroscope implements Dave Prosser's macro-replacement algorithm — iterative
splicing with per-token hide sets — so it shows expansion exactly the way
a conforming C23 preprocessor performs it (§6.10.5 + §6.10.3.5), including
the trickier cases like __VA_OPT__, paint-blocking, and deferred
expansion.
#define SQUARE(x) ((x) * (x))
SQUARE(3 + 4)
// → ((3 + 4) * (3 + 4))#define STR(x) #x
STR(hello world)
// → "hello world"#define CONCAT(a, b) a##b
CONCAT(foo, bar)
// → foobar#define LOG(fmt, ...) printf(fmt __VA_OPT__(,) __VA_ARGS__)
LOG("hi\n")
// → printf("hi\n")
LOG("%d\n", 42)
// → printf("%d\n", 42)#define EMPTY
#define DEFER(M) M EMPTY()
#define A() 123
DEFER(A)()
// → A () after first scan (A is hide-painted)
// → 123 after rescanThis is where most hand-rolled expanders go wrong — macroscope walks the hide-set bookkeeping token by token so you can see exactly why the second scan succeeds.
This is a macro-replacement simulator, not a full preprocessor. It deliberately doesn't handle:
- conditional compilation (
#if,#ifdef,#else,#elif,#endif) #include,#pragma,#embed,#error,#warning,#line- context-dependent predefined macros (
__FILE__,__LINE__, …)
All such directives are flagged in the live error strip as "not supported".