[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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.


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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]