m4-discuss
[Top][All Lists]

## Re: A little m4 puzzle

 From: Eric Blake Subject: Re: A little m4 puzzle Date: Mon, 12 Nov 2018 11:49:31 -0600 User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.0

```On 11/10/18 12:01 PM, Doug McIlroy wrote:
```
```Consider this predicate on strings.

define(eq,`define(`_\$1',F)define(`_2',T)_\$1')
```
```
Underquoted.  I highly recommend using full quoting:

define(`eq', `define(`_\$1', `F')define(`_2', `T')_\$1')

```
Also, did you mean for that _2 to be _\$2 instead? And do you want to undef your temporary variable(s) after the fact?
```
```
```
eq(x,y) yields T or F according as strings x and y are
the same or different. (The strings may contain only
characters allowed in macro names).
```
```
```
So you are (trying to) exploit the fact that if the strings are different, you define two separate temporary variables (assuming you meant _\$2); if they are equal, you redefine a single temporary variable.
```
```
```
The puzzle: If you omit inner quotes from the definition,
eq(A,A) yields T as intended. But what happens when you
repeat the test?
```
```
You mean, as in:

define(eq, `define(_\$1, F)define(_\$2, T)_\$1')

If so, then it's pretty easy to trace:

The first eq(A,A) expands to:

define(_A, F)define(_A, T)_A

which results in defining the macro "_A" to be "F" before expanding:

define(_A, T)_A

which is the same as:

define(F, T)_A

```
which defines the "F" to be "T", then expands the macro _A into F, and the macro F into T.
```
The second eq(A,A) expands to:

define(_A, F)define(_A, T)_A

where the first define is now the same as:

define(T, T)define(_A, T)_A

```
which defines the macro "T" to "T". At which point, ANY attempt to expand the macro T will infinitely recurse, which is exactly what happens when you reach the second define().
```
```
```
(Incidentally, you can replace T by `\$3' and F by `\$4'
to make a near replacement for the builtin ifelse.)
```
```
```
Not with your lack of proper quoting. And the builtin can handle any two strings, not just strings that are valid as part of a macro name.
```
--
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

```