Variable list in pre-processor define

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Allan Bruce

    #1

    Variable list in pre-processor define

    Is there a way to make a pre-processor define with a variable number of
    arguements? I want to have something like this:

    #define DBG_WRITE(char *A, ...)
    {
    va_list vl;
    char dbgTmpStr[1024];
    va_start(vl, A);
    vsprintf(dbgTmp Str, A, vl);
    va_end(vl);
    fprintf(gDbgFP, dbgTmpStr);
    fflush(gDbgFP);
    }

    But this obviously doesnt compile.
    At the moment I have DBG_WRITE0 for no additional params, DB_WRITE1 for 1
    additional param and so on which is quite messy.
    I can make a define that works for printf like this:

    #define DBG_PRINTF(A) printf A;
    and then I just call it like this: DBG_PRINTF(("He llo %s\n, someName));
    (note the double brackets).

    Is there a way I can achieve this for fprintf()?

    Thanks,
    Allan


  • Michael Mair

    #2
    Re: Variable list in pre-processor define



    Allan Bruce wrote:[color=blue]
    > Is there a way to make a pre-processor define with a variable number of
    > arguements? I want to have something like this:
    >
    > #define DBG_WRITE(char *A, ...)[/color]
    ^^^^^^
    You want to have a macro, not a function.[color=blue]
    > {
    > va_list vl;
    > char dbgTmpStr[1024];
    > va_start(vl, A);
    > vsprintf(dbgTmp Str, A, vl);
    > va_end(vl);
    > fprintf(gDbgFP, dbgTmpStr);
    > fflush(gDbgFP);
    > }
    >
    > But this obviously doesnt compile.
    > At the moment I have DBG_WRITE0 for no additional params, DB_WRITE1 for 1
    > additional param and so on which is quite messy.
    > I can make a define that works for printf like this:
    >
    > #define DBG_PRINTF(A) printf A;
    > and then I just call it like this: DBG_PRINTF(("He llo %s\n, someName));
    > (note the double brackets).
    >
    > Is there a way I can achieve this for fprintf()?[/color]

    In C99: Yes.
    #define DBG_WRITE(fmt, ...) \
    {\
    fprintf(gDbgFP, fmt, __VA_ARGS__);\
    fflush(gDbgFP); \
    }

    For function like macros, one usually does
    #define DBG_WRITE(fmt, ...) \
    do {\
    fprintf(gDbgFP, fmt, __VA_ARGS__);\
    fflush(gDbgFP); \
    } while (0)
    which works with
    if(....)
    DBG_WRITE("Fail ure (line %d)\n",__LINE__ );
    else
    ......
    (see clc FAQ)

    For C89, I suggest writing a vararg function and then
    calling v*printf().


    Cheers
    Michael
    --
    E-Mail: Mine is a gmx dot de address.

    Comment

    • Kevin Bracey

      #3
      Re: Variable list in pre-processor define

      In message <111jklrm73q2o0 3@corp.supernew s.com>
      "Allan Bruce" <abruce@TAKEMEA WAY.csd.abdn.ac .uk> wrote:
      [color=blue]
      > Is there a way to make a pre-processor define with a variable number of
      > arguements? I want to have something like this:
      >
      > #define DBG_WRITE(char *A, ...)
      > {
      > va_list vl;
      > char dbgTmpStr[1024];
      > va_start(vl, A);
      > vsprintf(dbgTmp Str, A, vl);
      > va_end(vl);
      > fprintf(gDbgFP, dbgTmpStr);
      > fflush(gDbgFP);
      > }
      >
      > But this obviously doesnt compile.
      > At the moment I have DBG_WRITE0 for no additional params, DB_WRITE1 for 1
      > additional param and so on which is quite messy.
      > I can make a define that works for printf like this:
      >
      > #define DBG_PRINTF(A) printf A;
      > and then I just call it like this: DBG_PRINTF(("He llo %s\n, someName));
      > (note the double brackets).
      >
      > Is there a way I can achieve this for fprintf()?[/color]

      C99 adds the feature of variadic macro arguments. Even if not fully
      C99-conformant, a lot of compilers will probably support at least this
      feature, as it's pretty easy:

      #define DBG_WRITE(...) \
      do { \
      fprintf(gDbgFP, __VA_ARGS__); \
      fflush(gDbgFP); \
      } while (0)

      The trailing macro parameter(s) that go in the position of the ellipsis are
      substituted into __VA_ARGS__. Unlike functions, it's legal to have the
      ellipsis and no named parameters.

      By the way, rather than have the fflush after every fprintf, it might be
      neater to change the buffering of gDbgFP to be line-based, or make it
      non-buffered, with a call to setvbuf.

      I also don't understand what the temporary buffer was about in your original
      example - why not vfprintf? It would also have had problems with "%"
      characters - the fprintf should have been fprintf(gDbgFP, "%s", dbgTmpStr).

      --
      Kevin Bracey, Principal Software Engineer
      Tematic Ltd Tel: +44 (0) 1223 503464
      182-190 Newmarket Road Fax: +44 (0) 1728 727430
      Cambridge, CB5 8HE, United Kingdom WWW: http://www.tematic.com/

      Comment

      • Allan Bruce

        #4
        Re: Variable list in pre-processor define

        > C99 adds the feature of variadic macro arguments. Even if not fully[color=blue]
        > C99-conformant, a lot of compilers will probably support at least this
        > feature, as it's pretty easy:
        >
        > #define DBG_WRITE(...) \
        > do { \
        > fprintf(gDbgFP, __VA_ARGS__); \
        > fflush(gDbgFP); \
        > } while (0)
        >
        > The trailing macro parameter(s) that go in the position of the ellipsis
        > are
        > substituted into __VA_ARGS__. Unlike functions, it's legal to have the
        > ellipsis and no named parameters.
        >
        > By the way, rather than have the fflush after every fprintf, it might be
        > neater to change the buffering of gDbgFP to be line-based, or make it
        > non-buffered, with a call to setvbuf.
        >
        > I also don't understand what the temporary buffer was about in your
        > original
        > example - why not vfprintf? It would also have had problems with "%"
        > characters - the fprintf should have been fprintf(gDbgFP, "%s",
        > dbgTmpStr).
        >[/color]


        Thanks for the replies - doesn't look as if Visual Studio supports this :-(
        Allan


        Comment

        • SM Ryan

          #5
          Re: Variable list in pre-processor define

          "Allan Bruce" <abruce@TAKEMEA WAY.csd.abdn.ac .uk> wrote:
          # Is there a way to make a pre-processor define with a variable number of
          # arguements? I want to have something like this:


          #ifdef DEBUGGING
          void DBG_WRITE(char *A,...) {
          va_list vl;
          va_start(vl, A);
          vfprintf(gDbgFP , A, vl);
          va_end(vl);
          fflush(gDbgFP);
          }
          #else
          #define DBG_WRITE (void)
          #endif

          --
          SM Ryan http://www.rawbw.com/~wyrmwif/
          I'm not even supposed to be here today.

          Comment

          Working...