# Macro expansion is done in which phase of a compiler?

This is question raised by my teacher in the class room. I don't have enough knowledge about phases of compiler and macro expansion. Could someone help me in finding out proper solution to this

• You should probably review your class notes, or do some independent research. The question may also not have a universal answer. Also, what are macros, in general? – Raphael Nov 19 '15 at 11:50

It's completely dependent on the language. Different languages have wildly different notions of macros. I'll just give a few examples; other situations are possible.

### The original C language (K&R C)

Macros are expanded by the preprocessor, which is a separate program that runs before the compiler proper. Macros perform a simple text substitution. This program prints 1, because PLUS()PLUS() expands to ++ which is the increment operator.

#include <stdio.h>
#define PLUS() +
int main()
{
int x = 0;
PLUS()PLUS()x;
printf("%d\n", x);
return 0;
}


### The modern C language (ANSI C)

Macros are expanded by the preprocessor, which acts on tokens, after lexical analysis. Thus, a macro only expands to whole tokens, but can contain things like unbalanced parentheses. The program above prints 0, because each PLUS() expands to a + token, so the instruction is equivalent to + + x;.

### Lisp

Macros act on the program's representation as an abstract syntax tree, i.e. after parsing. Thus a macro expands to a sexp (Lisp's term for an abstract syntax tree), and its arguments are themselves sexps. Macros are expanded before variable resolution. Such macros are said to be unhygienic. Care must be taken not to mix up variables introduced by a macro from the variables of the program fragments.

(defmacro repeat (count func)
(loop for i from 1 to ,count
do (apply ,func nil)))
(repeat 3 (lambda () (print "hello")))
(let ((i 5))
(repeat 3 (lambda () (print i))))


The first call to repeat prints hello three times as expected. The second call to repeat does not print 5 three times, it prints 1 then 2 then 3, because the variable i from the macro shadows the variable i from the context of the macro call.

### Scheme

Scheme is similar to Lisp, but with a few differences. One of the differences is that Scheme macros are hygienic. The Scheme equivalent of the program above prints hello three times then 5 three times.

(define-syntax repeat
(syntax-rules ()
((repeat count func)
(do ((i 1 (+ 1 i)))
((> i count))
(func)))))
(repeat 3 (lambda () (display "hello") (newline)))
(let ((i 5))
(repeat 3 (lambda () (display i) (newline))))
`

### TeX

TeX expands macros in its mouth but defines them in its stomach. But don't set too much store by this: from a language design perspective, TeX is weird.

• The shape of this answer suggests that this question should not be here. Can you suggest a better site for it? – Raphael Nov 20 '15 at 8:29
• @Raphael The question could live on either Computer Science or Stack Overflow, but I think SO wouldn't do it justice. This is fundamentally a science question, but one for which the answer happens to be “there's no real scientific foundation to it”. That's my first sentence, but it would make for a pretty boring answer if I didn't illustrate with examples. Analogy: the question “what colors can plants be?” calls for a biology answer that discusses clorophyll. A natural follow-up question could be “what colors can birds be?” which doesn't have any similar answer (or would it discuss plumage and mating?). – Gilles 'SO- stop being evil' Nov 20 '15 at 12:10

Macro expansion is done by a preprocessor before the compiler ever looks at the file. This is at least how it works in C/C++.

• This is not how it works in Clang. (It's also, obviously, not how it works in Common Lisp, Dylan, Rust, Julia...) – Pseudonym Nov 19 '15 at 12:28
• Arc even does macro expansion at run-time! – Dave Clarke Nov 19 '15 at 13:22