Macro with a default value

Discussion in 'C Programming' started by aleksa, Nov 14, 2010.

  1. aleksa

    aleksa Guest

    I would like to have a "dofor" macro which would use
    either a suplied loop variable or a default loop variable (f).

    dofor(512, i) // should be expanded to
    for (i = 512; i != 0; i--)

    dofor(512) // should be expanded to
    for (f = 512; f != 0; f--)

    Could someone give me some pointers here?
     
    aleksa, Nov 14, 2010
    #1
    1. Advertisements

  2. aleksa

    Tom St Denis Guest

    On Nov 14, 6:08 am, "aleksa" <> wrote:
    > I would like to have a "dofor" macro which would use
    > either a suplied loop variable or a default loop variable (f).
    >
    > dofor(512, i) // should be expanded to
    > for (i = 512; i != 0; i--)
    >
    > dofor(512) // should be expanded to
    > for (f = 512; f != 0; f--)
    >
    > Could someone give me some pointers here?


    Good preprocessor question, but I'd like to just step in here and say:
    "Don't write code like this."

    Replacing single statements with macros is a surefire way to make your
    code completely unmaintainable. Don't do it if you have any hope of
    working on it long term.

    Tom
     
    Tom St Denis, Nov 14, 2010
    #2
    1. Advertisements

  3. aleksa

    Stefan Ram Guest

    "aleksa" <> writes:
    >dofor(512, i) // should be expanded to
    >for (i = 512; i != 0; i--)
    >dofor(512) // should be expanded to
    >for (f = 512; f != 0; f--)


    I does not work as follows,
    but maybe someone can improve on this?

    #define test(x) \
    0/x/2; printf( "%s\n", #x ); if( 0 )\
    +printf( "f\n" );

    The idea is that with »test(i)«, this expands to

    0/i/2; printf( "%s\n", "i" ); if( 0 )
    +printf( "f\n" );

    i.e., effectively,

    printf( "%s\n", "i" );

    , which should print the line »i«, while »test()«
    expands to

    0//2; printf( "%s\n", "i" ); if( 0 )
    +printf( "f\n" );

    , effectively,

    0+printf( "f\n" );

    , which should print the line »f«. However, it seems
    that the »/« do not form a single »//« token this way.
     
    Stefan Ram, Nov 14, 2010
    #3
  4. aleksa

    Eric Sosman Guest

    On 11/14/2010 7:39 AM, Stefan Ram wrote:
    > "aleksa"<> writes:
    >> dofor(512, i) // should be expanded to
    >> for (i = 512; i != 0; i--)
    >> dofor(512) // should be expanded to
    >> for (f = 512; f != 0; f--)

    >
    > I does not work as follows,
    > but maybe someone can improve on this?
    >
    > #define test(x) \
    > 0/x/2; printf( "%s\n", #x ); if( 0 )\
    > +printf( "f\n" );
    >
    > The idea is that with »test(i)«, this expands to
    >
    > 0/i/2; printf( "%s\n", "i" ); if( 0 )
    > +printf( "f\n" );
    >
    > i.e., effectively,
    >
    > printf( "%s\n", "i" );
    >
    > , which should print the line »i«, while »test()«
    > expands to
    >
    > 0//2; printf( "%s\n", "i" ); if( 0 )
    > +printf( "f\n" );
    >
    > , effectively,
    >
    > 0+printf( "f\n" );
    >
    > , which should print the line »f«. However, it seems
    > that the »/« do not form a single »//« token this way.


    Right, because comments are recognized and removed in phase 3,
    before the preprocessor does its work in phase 4. See section 5.1.1.2
    "Translation phases."

    --
    Eric Sosman
    lid
     
    Eric Sosman, Nov 14, 2010
    #4
  5. aleksa

    Seebs Guest

    On 2010-11-14, aleksa <> wrote:
    > I would like to have a "dofor" macro which would use
    > either a suplied loop variable or a default loop variable (f).
    >
    > dofor(512, i) // should be expanded to
    > for (i = 512; i != 0; i--)
    >
    > dofor(512) // should be expanded to
    > for (f = 512; f != 0; f--)
    >
    > Could someone give me some pointers here?


    You can't do optional-argument macros.

    Furthermore, don't do this. Several reasons, not the least of which is
    that you're counting backwards which will usually surprise people, and
    you should never hide simple basic syntax behind macros.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
    I am not speaking for my employer, although they do rent some of my opinions.
     
    Seebs, Nov 14, 2010
    #5
  6. Seebs <> writes:
    > On 2010-11-14, aleksa <> wrote:
    >> I would like to have a "dofor" macro which would use
    >> either a suplied loop variable or a default loop variable (f).
    >>
    >> dofor(512, i) // should be expanded to
    >> for (i = 512; i != 0; i--)
    >>
    >> dofor(512) // should be expanded to
    >> for (f = 512; f != 0; f--)
    >>
    >> Could someone give me some pointers here?

    >
    > You can't do optional-argument macros.
    >
    > Furthermore, don't do this. Several reasons, not the least of which is
    > that you're counting backwards which will usually surprise people, and
    > you should never hide simple basic syntax behind macros.


    C99 added variadic macros. You *might* be able to do something like:

    #define dofor(count, ...) /* something */

    so at least both dofor(512, i) and dofor(512) would be legal. But I
    can't think of a way to make this work for what the OP is asking about
    (not that I tried very hard).

    To the OP: If you're going to do this, at least use all-caps for the
    macro name. (The convention of using all-caps for macro names is
    intended to make them stand out, so it's obvious to the reader that
    something strange is going on.)

    For that matter, there's not that much benefit in using a single name
    for both. If you want the loop variable name to default to i (yours
    defaults to f, but i makes more sense), you could just write:

    #define DOFOR(count, var) for ((var) = (count); (var) != 0; (var)--)
    #define DOFORI(count) for (i = (count); i != 0; i--)

    Or, if you can depend on having a C99 compiler, or at least one that
    supports declarations in for loops as an extension:

    #define DOFOR(count, var) for (int var = (count); (var) != 0; (var)--)
    #define DOFORI(count) for (int i = (count); i != 0; i--)

    You have to know how many arguments you're using when you write the
    call; using distinct names isn't much of an added burden.

    But these are all improvements on a bad idea. A better solution is
    just to write ordinary for loops; they're going to be much more
    legible to anyone reading your code (including you six months
    from now).

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Nov 14, 2010
    #6
    1. Advertisements

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. Dead RAM
    Replies:
    20
    Views:
    1,320
    John Harrison
    Jul 14, 2004
  2. D Senthil Kumar

    macro name from macro?

    D Senthil Kumar, Sep 20, 2003, in forum: C Programming
    Replies:
    1
    Views:
    715
    Jack Klein
    Sep 21, 2003
  3. Keith Thompson

    Re: Challenging macro with default value

    Keith Thompson, Apr 1, 2004, in forum: C Programming
    Replies:
    7
    Views:
    383
    cturtle
    Apr 6, 2004
  4. Dan Pop

    Re: Challenging macro with default value

    Dan Pop, Apr 1, 2004, in forum: C Programming
    Replies:
    12
    Views:
    552
    Keith Thompson
    Apr 2, 2004
  5. sounak

    to get macro name from macro value

    sounak, Nov 22, 2005, in forum: C Programming
    Replies:
    17
    Views:
    589
    Mark McIntyre
    Nov 22, 2005
Loading...

Share This Page