Code blocks as macro parameters

Discussion in 'C Programming' started by Alexander Ulyanov, Aug 20, 2004.

  1. Hi all.

    Is it possible to pass the whole blocks of code (possibly including
    " and ,) as macro parameters?

    I want to do something like:

    MACRO(FOO, "Foo",
    "return "Foobar";",
    "foo(); bar();")

    (just an example, obviously this won't compile)

    being parsed to:

    1.
    P_FOO, /* Part of enum */
    2.
    "FOO", /* Part of string literal array */
    3.
    "Foo", /* Part of string literal array */
    4.
    case P_FOO: /* Part of switch */
    return "Foobar";
    break;
    5.
    case P_FOO: /* Part of switch */
    foo(); bar();
    break;

    Depending on some #define, of course. I don't want to edit five
    source files to add or remove something; keeping them consistent
    is difficult.

    I'm currently doing this with a m4 macro and it works fine, but I'd
    like to avoid using an extra tool (which may not be available on
    Windows or other non-UNIX systems).

    --
    Alexander Ulyanov, maintainer of PosBand roguelike
    E-mail: uav AT urmail DOT ru Web: http://orthanc.chat.ru/pos/
    "...And his name is Melkor, Lord of All, Giver of Freedom, and he shall
    make you stronger that they." -- Akallabeth, the Downfall of Numenor
     
    Alexander Ulyanov, Aug 20, 2004
    #1
    1. Advertising

  2. Alexander Ulyanov

    SM Ryan Guest

    Alexander Ulyanov <> wrote:
    # Hi all.
    #
    # Is it possible to pass the whole blocks of code (possibly including
    # " and ,) as macro parameters?

    cat <<':eof' >/tmp/xx.c
    #define repeat_until(block,predicate) do {block} while (!(predicate)
    (1); repeat_until(x = f(x);,x>0);
    (2); repeat_until(x = f(y,"b"); y = g(x,"a");,x>0);
    (3); repeat_until(repeat_until(y=f(y);,y>0),x>0);
    (4); repeat_until({int x,y; x=h(x,y);},z);
    (5); repeat_until(int x,y; x=h(x,y);,z);
    (6); repeat_until(int x; int y; x=h(x,y);,z);
    :eof
    cc -E /tmp/xx.c

    The preprocessor is only looking for comma and parentheses. Parentheses
    have to be balanced and commas outside of parentheses are argument
    separators. You can almost always avoid commas: comma expressions
    can be parenthesised, and joined declarations (like int x,y;) can be
    separated (int x; int y;).

    --
    SM Ryan http://www.rawbw.com/~wyrmwif/
    Quit killing people. That's high profile.
     
    SM Ryan, Aug 20, 2004
    #2
    1. Advertising

  3. On 2004-08-20, SM Ryan <> wrote:
    > Alexander Ulyanov <> wrote:
    > # Hi all.
    > #
    > # Is it possible to pass the whole blocks of code (possibly including
    > # " and ,) as macro parameters?
    >
    > cat <<':eof' >/tmp/xx.c
    > #define repeat_until(block,predicate) do {block} while (!(predicate)
    > (1); repeat_until(x = f(x);,x>0);
    > (2); repeat_until(x = f(y,"b"); y = g(x,"a");,x>0);
    > (3); repeat_until(repeat_until(y=f(y);,y>0),x>0);
    > (4); repeat_until({int x,y; x=h(x,y);},z);
    > (5); repeat_until(int x,y; x=h(x,y);,z);
    > (6); repeat_until(int x; int y; x=h(x,y);,z);
    >:eof
    > cc -E /tmp/xx.c
    >
    > The preprocessor is only looking for comma and parentheses. Parentheses
    > have to be balanced and commas outside of parentheses are argument
    > separators. You can almost always avoid commas: comma expressions
    > can be parenthesised, and joined declarations (like int x,y;) can be
    > separated (int x; int y;).


    Thanks!

    --
    Alexander Ulyanov, maintainer of PosBand roguelike
    E-mail: uav AT urmail DOT ru Web: http://orthanc.chat.ru/pos/
    "...And his name is Melkor, Lord of All, Giver of Freedom, and he shall
    make you stronger that they." -- Akallabeth, the Downfall of Numenor
     
    Alexander Ulyanov, Aug 21, 2004
    #3
  4. Alexander Ulyanov

    Old Wolf Guest

    Alexander Ulyanov <> wrote:
    > Hi all.
    >
    > Is it possible to pass the whole blocks of code (possibly including
    > " and ,) as macro parameters?
    >
    > I want to do something like:
    >
    > MACRO(FOO, "Foo",
    > "return "Foobar";",
    > "foo(); bar();")
    >
    > (just an example, obviously this won't compile)


    Regarding the code snippets, you can use an expression in brackets:
    ( foo(), bar() )
    My experience is that using a single expression is preferable
    to a set of statements, if possible.

    In this case it is possible to avoid having the "return" as part
    of the macro definition (see below).

    > being parsed to:
    >
    > 1.
    > P_FOO, /* Part of enum */
    > 2.
    > "FOO", /* Part of string literal array */
    > 3.
    > "Foo", /* Part of string literal array */
    > 4.
    > case P_FOO: /* Part of switch */
    > return "Foobar";
    > break;


    No need to 'break' if you have just returned :)

    > 5.
    > case P_FOO: /* Part of switch */
    > foo(); bar();
    > break;
    >
    > Depending on some #define, of course. I don't want to edit five
    > source files to add or remove something; keeping them consistent
    > is difficult.


    Obviously you can't invoke the definition once and then have it copy
    the code to various places; you will have to define a new meaning
    for the macro when you want to use it. If the "calls" to MACRO()
    are in "macro.h" then you could go:

    enum {
    #define MACRO(a,b,c,d) P_##a,
    #include "macro.h"
    #undef MACRO
    };
    char const *foo1 = {
    #define MACRO(a,b,c,d) #a,
    #include "macro.h"
    #undef MACRO
    NULL /* trailing commas are not portable */
    };

    switch(bar) {
    #define MACRO(a,b,c,d) case P_##a: d; return c;
    #include "macro.h"
    #undef MACRO
    };

    etc.
     
    Old Wolf, Aug 23, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Arjen
    Replies:
    3
    Views:
    447
    Scott Allen
    Feb 27, 2005
  2. Dead RAM
    Replies:
    20
    Views:
    1,118
    John Harrison
    Jul 14, 2004
  3. D Senthil Kumar

    macro name from macro?

    D Senthil Kumar, Sep 20, 2003, in forum: C Programming
    Replies:
    1
    Views:
    582
    Jack Klein
    Sep 21, 2003
  4. matt
    Replies:
    1
    Views:
    273
    George Ogata
    Aug 6, 2004
  5. Steven Taylor
    Replies:
    9
    Views:
    256
    Brian Candler
    Apr 27, 2009
Loading...

Share This Page