Re: A little m4 puzzle
Eric Blake <[email protected]> Mon, 12 Nov 2018 11:49:31 -0600
| Newsgroups | gmane.comp.gnu.m4.general |
|---|---|
| Organization | Red Hat, Inc. |
| Message-ID | <[email protected]> |
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