Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

macro chain

18 views
Skip to first unread message

luser- -droog

unread,
Mar 14, 2012, 12:47:52 AM3/14/12
to
I remember reading something from Knuth to the effect that you don't
really need multiple argument macros because you can yield a macro
name from the macro expansion and call that with a new argument.

So I tried a little experiment:

#define A(x) x + B
#define B(y) y y y
A(2)(3)

And I'll be darned if gcc -E doesn't produce:

2 + 3 3 3

But I'm not really doing this right, am I? Does anyone have
suggestions for where I could learn more? (more Knuth?)

--
The mystery of luserdroog

io_x

unread,
Mar 14, 2012, 1:00:40 AM3/14/12
to

"luser- -droog" <mij...@yahoo.com> ha scritto nel messaggio
news:b2008229-ce07-4b57...@a20g2000yql.googlegroups.com...
better not use C macro if not in these case:
#define whatIsThisNumber 89
#define B 73
#define u32 unsigned int
#define R return

better to write
u32 A(u32 x){R x+B;}
than #define A(x) x + B

but i'm one C expert so i see it not in the way here people want

Ian Collins

unread,
Mar 14, 2012, 12:59:18 AM3/14/12
to
On 03/14/12 06:00 PM, io_x wrote:
> "luser- -droog"<mij...@yahoo.com> ha scritto nel messaggio
> news:b2008229-ce07-4b57...@a20g2000yql.googlegroups.com...
>> I remember reading something from Knuth to the effect that you don't
>> really need multiple argument macros because you can yield a macro
>> name from the macro expansion and call that with a new argument.
>>
>> So I tried a little experiment:
>>
>> #define A(x) x + B
>> #define B(y) y y y
>> A(2)(3)
>>
>> And I'll be darned if gcc -E doesn't produce:
>>
>> 2 + 3 3 3
>>
>> But I'm not really doing this right, am I? Does anyone have
>> suggestions for where I could learn more? (more Knuth?)
>
> better not use C macro if not in these case:
> #define whatIsThisNumber 89
> #define B 73
> #define u32 unsigned int
> #define R return

No!


--
Ian Collins

io_x

unread,
Mar 14, 2012, 1:25:20 AM3/14/12
to

"io_x" <a...@b.c.invalid> ha scritto nel messaggio
news:4f6024ec$0$1379$4faf...@reader2.news.tin.it...
>
> better not use C macro if not in these case:
> #define whatIsThisNumber 89
> #define B 73
> #define u32 unsigned int
> #define R return
>
> better to write
> u32 A(u32 x){R x+B;}
> than #define A(x) x + B
>
> but i'm one C expert so i see it not in the way here people want

but i'm not one C expert so i see it not in the way here people want
Ciao


Ben Bacarisse

unread,
Mar 14, 2012, 8:54:06 AM3/14/12
to
Not all macro processors are created equal. The big difference between
C's macro processor and many others (TeX, m4, Lisp, TRAC, ...) is that a
macro expansion can't define new macros (in fact they can't generate
*any* macro processing directives).

Knuth's remark may well be about macro systems that can mirror what
functional languages often do for multiple-argument functions (looking
up Currying and partial application may give you more about this -- it's
off topic enough that I don't want to go into it here). Though I don't
know the Knuth document in question, I suspect he is referring to macros
that work in a similar way.

In C+ it might look a bit like this:

#define ADD(x) #define ADD_(y) x + y \
ADD_

An invocation of ADD(3) produces a new definition of a macro called
ADD_ which generates code to add 3 to its argument along with a call to
this macro left "hanging". ADD(3)(4) would then yield 3 + 4.

To do this properly, you'd want ADD_ to remove its own definition and
you'd want definitions to "stack" so that the new (temporary) definition
does not interfere with any existing one, and some macro systems allow
new, unique, names to be generated thus avoiding the need to pick
a name for the temporary macro.

--
Ben.

Eric Sosman

unread,
Mar 14, 2012, 9:05:49 AM3/14/12
to
This should work, but only for "tail-chaining" expansions,
that is, where the very last thing in the first macro's replacement
list is the name of the second macro.

For example, to put parentheses around the entire expansion
you could not just change A to

#define A(x) ( x + B )

... but you'd have to change both macros, something like

#define A(x) ( x + B
#define B(y) y y y )

If the first macro's argument must expand after the second
macro, I think even this won't suffice. For example, consider
a simple two-argument macro like

#define MAX(x,y) ( (x) > (y) ? (x) : (y) )
int max = MAX(42,17);

... and try to build an equivalent "chain" of one-argument macros:

#define AMAX(x) // your answer here
#define BMAX(y) // your answer here
int max = AMAX(42)(17);

I think the fact that the 42 must appear both before and after
the 17 means you're sunk.

--
Eric Sosman
eso...@ieee-dot-org.invalid

luser- -droog

unread,
Mar 14, 2012, 11:56:11 AM3/14/12
to
Thanks, Eric and Ben.
Just what I needed!

io_x, thanks for trying!
0 new messages