cshu
cshu

Reputation: 5944

Expansion of nested macros, from the inner to the outer?

I stumbled across this line in the book C: From Theory to Practice, p.436:

"The preprocessor expands the nested macros from the inner to the outer."

But I thought it's expanded from outer to inner. Was I wrong all along?

For example, you have macros #define FUNC(x,y) x+y and #define PARA 3,4, but you cannot use FUNC(PARA). I thought FUNC gets expanded before PARA.

Similarly, when you do stringification like #define str(s) #s, using str(__LINE__) results in "__LINE__".

I'm confused.

If nested macros are expanded from the inner to the outer, then how to understand these 2 examples?

Upvotes: 3

Views: 1462

Answers (1)

user2371524
user2371524

Reputation:

The answer is these aren't nested macros, but macros in parameters. There might be some confusion because some sources nevertheless talk about them as "nested" macros. But indeed, parameters are expanded later.

A nested macro is a macro inside the replacement list of another macro. These are expanded before the macro containing them is expanded.

see for example:

#define foo "foo" bar baz
#define bar "bar" baz foo
#define baz "baz" foo bar

foo
bar
baz

results in the following expansion:

"foo" "bar" "baz" foo bar foo "baz" foo "bar" baz foo
"bar" "baz" "foo" bar baz bar "foo" bar "baz" foo bar
"baz" "foo" "bar" baz foo baz "bar" baz "foo" bar baz

What happens (only explaining the first line in detail)?

1.  [1][foo] bar is found -> expand this first
2.  [2][bar] baz is found -> expand this first
3.  [3][baz] foo is found -> already in "foo" expansion, ignore
4.  [3][baz] bar is found -> already in "bar" expansion, ignore
5.  [3][baz] baz expands to ["baz" foo bar]
6.  [2][bar] foo is found -> already in "foo" expansion, ignore
7.  [2][bar] bar expands to ["bar" "baz" foo bar foo] <- note baz was expanded before bar
8.  [1][foo] baz is found -> expand this first
9.  [2][baz] foo is found -> already in "foo" expansion, ignore
10. [2][baz] bar is found -> expand this first
11. [3][bar] baz is found -> already in "baz" expansion, ignore
12. [3][bar] foo is found -> already in "foo" expansion, ignore
13. [3][bar] bar expands to ["bar" baz foo]
14. [2][baz] baz expands to ["baz" foo "bar" baz foo] <- note bar was expanded first
15. [1][foo] foo expands to ["foo" { "bar" "baz" foo bar foo } { "baz" foo "bar" baz foo } ]

Note: In line 15, I used the curly braces {} to mark the expansions of the nested macros. The number in the brackets [] is the nesting level during expansion. The next bracket shows the name of the macro currently expanded.

While descending to the innermost nested macro, the preprocessor knows what macros it currently tries to expand and doesn't attempt to expand them nested, to avoid recursive expansion.

Upvotes: 4

Related Questions