Question about #define

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jorge Naxus

    Question about #define

    Hello

    I would like to write a macro like that:

    #ifdef DEBUG
    #define printj(...) printf(...)
    #else
    #printj(...)
    #endif

    So that printj behaves exactly like printf when DEBUG is true and
    doesnt do anything when DEBUG is false.
    But I dont know how to deal with the variable number of arguments of
    printf(...).

    Any help on how should be my "define"??

    Thanks,

    Jorge
  • Frank van Eijkelenburg

    #2
    Re: Question about #define

    You can use:

    #ifdef DEBUG
    #define printj(x) printf((x))
    #else
    #define printj(x)
    #endif

    but now you should use printj as: printj(("just a test\n"));

    AFAIK macros don't support a variable number of arguments.

    Frank

    "Jorge Naxus" <egrojorge@terr a.es> wrote in message
    news:dcb21ca0.0 403010710.1b201 ccc@posting.goo gle.com...[color=blue]
    > Hello
    >
    > I would like to write a macro like that:
    >
    > #ifdef DEBUG
    > #define printj(...) printf(...)
    > #else
    > #printj(...)
    > #endif
    >
    > So that printj behaves exactly like printf when DEBUG is true and
    > doesnt do anything when DEBUG is false.
    > But I dont know how to deal with the variable number of arguments of
    > printf(...).
    >
    > Any help on how should be my "define"??
    >
    > Thanks,
    >
    > Jorge[/color]


    Comment

    • Leor Zolman

      #3
      Re: Question about #define

      On 1 Mar 2004 07:10:01 -0800, egrojorge@terra .es (Jorge Naxus) wrote:
      [color=blue]
      >Hello
      >
      >I would like to write a macro like that:
      >
      >#ifdef DEBUG
      >#define printj(...) printf(...)
      >#else
      >#printj(...)
      >#endif
      >
      >So that printj behaves exactly like printf when DEBUG is true and
      >doesnt do anything when DEBUG is false.
      >But I dont know how to deal with the variable number of arguments of
      >printf(...).
      >
      >Any help on how should be my "define"??[/color]

      C99 does (as I just discovered to my complete surprise by Googling)
      support variadic macros! So if you're coding in C99 you're all set.

      Otherwise, I'd probably approach this by creating an ordinary (non-macro)
      variadic printj function inside of which, via conditional compilation
      (based presumably on your DEBUG symbol), either hands off to a
      printf-family function (e.g. vprintf) or doesn't.
      -leor
      [color=blue]
      >
      >Thanks,
      >
      >Jorge[/color]

      Leor Zolman
      BD Software
      leor@bdsoft.com
      www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
      C++ users: Download BD Software's free STL Error Message
      Decryptor at www.bdsoft.com/tools/stlfilt.html

      Comment

      • CBFalconer

        #4
        Re: Question about #define

        Jorge Naxus wrote:[color=blue]
        >
        > I would like to write a macro like that:
        >
        > #ifdef DEBUG
        > #define printj(...) printf(...)
        > #else
        > #printj(...)
        > #endif
        >
        > So that printj behaves exactly like printf when DEBUG is true and
        > doesnt do anything when DEBUG is false. But I dont know how to
        > deal with the variable number of arguments of printf(...).
        >
        > Any help on how should be my "define"??[/color]

        You have two choices.

        1. Get and use a C99 compiler. Then your code will no longer port
        to a C90 compiler.

        2. Get and use gcc and the gnu variadic macro extensions. Then
        your code will no longer port to a non-gnu compiler. If you get a
        late enough gcc you can combine with option 1, because the latest
        gccs handle C99 variadic macros in addition to the gnu flavor.

        The only example I can show you is in nmalloc.zip, available on my
        page, download section. It is using exactly those facilities, and
        is thus limited to gcc compilation.

        --
        Chuck F (cbfalconer@yah oo.com) (cbfalconer@wor ldnet.att.net)
        Available for consulting/temporary embedded and systems.
        <http://cbfalconer.home .att.net> USE worldnet address!

        Comment

        • Mark Henning

          #5
          Re: Question about #define

          news:dcb21ca0.0 403010710.1b201 ccc@posting.goo gle.com...[color=blue]
          > Hello
          >
          > I would like to write a macro like that:
          >
          > #ifdef DEBUG
          > #define printj(...) printf(...)
          > #else
          > #printj(...)
          > #endif
          >
          > So that printj behaves exactly like printf when DEBUG is true and
          > doesnt do anything when DEBUG is false.
          > But I dont know how to deal with the variable number of arguments of
          > printf(...).
          >
          > Any help on how should be my "define"??
          >
          > Thanks,
          >
          > Jorge[/color]

          I normally end up creating about 5 seporate macros for the task.

          #ifdef DEBUGMODE
          #define DEBUG_PRINT(a) printf(a)
          #define DEBUG_PRINT1(a, b) printf(a,b)

          etc, etc..

          inelegant, but it works fine for me.


          Comment

          • Francois Grieu

            #6
            Re: Question about #define

            In article <4043578a$0$651 53$d5255a0c@new s.versatel.net> ,
            "Frank van Eijkelenburg" <someone@work.c om> wrote:
            [color=blue]
            > #ifdef DEBUG
            > #define printj(x) printf((x))
            > #else
            > #define printj(x)
            > #endif
            >
            > but now you should use printj as: printj(("just a test\n"));[/color]

            probably Frank meant:

            #ifdef DEBUG
            #define printj(x) printf x
            #else
            #define printj(x)
            #endif

            but now you should use printj as:
            printj(("just a test\n"));
            printj(("%d %d %d\n",1,2,3));

            and must NOT use
            printj(("%d\n", ++j));

            [not tested]

            François Grieu

            Comment

            • John Cochran

              #7
              Re: Question about #define

              In article <dcb21ca0.04030 10710.1b201ccc@ posting.google. com>,
              Jorge Naxus <egrojorge@terr a.es> wrote:[color=blue]
              >Hello
              >
              >I would like to write a macro like that:
              >
              >#ifdef DEBUG
              >#define printj(...) printf(...)
              >#else
              >#printj(...)
              >#endif
              >
              >So that printj behaves exactly like printf when DEBUG is true and
              >doesnt do anything when DEBUG is false.
              >But I dont know how to deal with the variable number of arguments of
              >printf(...).
              >
              >Any help on how should be my "define"??
              >
              >Thanks,
              >
              >Jorge[/color]

              I see two possible solutions.
              1. If you are using a C99 compatable compiler, then what you want is

              #ifdef DEBUG
              #define printj(...) printf(__VA_ARG S__)
              #else
              #define printj(...) ((void)0)
              #endif

              2. If you are using a C89 compatable compiler, then the following will work.


              #ifdef DEBUG
              #define printj printf
              #else
              #define printj (void)
              #endif


              The 2nd method requires a little bit of explaining and has some drawbacks.
              When DEBUG is defined, I believe that you'll see that it does what you want.
              If DEBUG isn't defined, what you'll see is that you get a series of comma
              seperated expressions inside parens and the final result of these expressions
              is then cast to void. This behaivor is also what you want. The drawback
              is that the printj macro isn't a function-like macro and therefore everywhere
              the compiler sees printj, it will make the subsitution. For example, look
              at the following code:

              int main(void)
              {
              int printj;

              for(printj=0; printj < 10; ++printj) {
              printf("%d\n", printj);
              }
              return 0;
              }

              The above example is perfectly legal using the macros for C99, but will fail
              to compile using the macros for C89.

              Hope this helps,
              John Cochran

              Comment

              • Stan Tobias

                #8
                Re: Question about #define

                John Cochran <jdc@smof.fiawo l.org> wrote:[color=blue]
                > #ifdef DEBUG
                > #define printj printf
                > #else
                > #define printj (void)
                > #endif[/color]

                [color=blue]
                > The 2nd method requires a little bit of explaining and has some drawbacks.
                > When DEBUG is defined, I believe that you'll see that it does what you want.
                > If DEBUG isn't defined, what you'll see is that you get a series of comma
                > seperated expressions inside parens and the final result of these expressions
                > is then cast to void. This behaivor is also what you want. The drawback[/color]

                One other drawback is that all sub-expressions within the comma-expression
                are evaluated, all side-effects apply, and that might not be what
                you want.

                --
                Stan Tobias

                Comment

                • John Cochran

                  #9
                  Re: Question about #define

                  In article <c202pm$1mpdem$ 1@ID-223330.news.uni-berlin.de>,
                  Stan Tobias <sNOiSPAMt@amu. edu.pl> wrote:[color=blue]
                  >John Cochran <jdc@smof.fiawo l.org> wrote:[color=green]
                  >> #ifdef DEBUG
                  >> #define printj printf
                  >> #else
                  >> #define printj (void)
                  >> #endif[/color]
                  >
                  >[color=green]
                  >> The 2nd method requires a little bit of explaining and has some drawbacks.
                  >> When DEBUG is defined, I believe that you'll see that it does what you want.
                  >> If DEBUG isn't defined, what you'll see is that you get a series of comma
                  >> seperated expressions inside parens and the final result of these expressions
                  >> is then cast to void. This behaivor is also what you want. The drawback[/color]
                  >
                  >One other drawback is that all sub-expressions within the comma-expression
                  >are evaluated, all side-effects apply, and that might not be what
                  >you want.[/color]

                  True, but if you have side effects in your debug statements, then something
                  is seriously wrong with your code and/or design because you will get different
                  results from your code depending on if debug is enabled or not.

                  Comment

                  • Old Wolf

                    #10
                    Re: Question about #define

                    > I would like to write a macro like that:[color=blue]
                    >
                    > #ifdef DEBUG
                    > #define printj(...) printf(...)[/color]

                    #define printj printf
                    [color=blue]
                    > #else
                    > #printj(...)[/color]

                    #define printj
                    [color=blue]
                    > #endif
                    >
                    > So that printj behaves exactly like printf when DEBUG is true and
                    > doesnt do anything when DEBUG is false.[/color]

                    NB. Avoid using printj's return value

                    NB2. You say "doesnt do anything". All the solutions offered so far
                    do evaluate printj's arguments (eg. if you went: printj("%d", foo());
                    then foo gets called). To prevent this you will have to use the
                    normal method of #ifdef etc. around each printf.

                    Comment

                    • Arthur J. O'Dwyer

                      #11
                      Re: Question about #define


                      On Mon, 1 Mar 2004, Old Wolf wrote:[color=blue]
                      >[color=green]
                      > > I would like to write a macro like that:
                      > >
                      > > #ifdef DEBUG
                      > > #define printj(...) printf(...)[/color]
                      >
                      > #define printj printf
                      >[color=green]
                      > > #else
                      > > #printj(...)[/color]
                      >
                      > #define printj
                      >[color=green]
                      > > #endif
                      > >
                      > > So that printj behaves exactly like printf when DEBUG is true and
                      > > doesnt do anything when DEBUG is false.[/color]
                      >
                      > NB. Avoid using printj's return value[/color]

                      ....because in reality 'printj' doesn't have a return value; it has
                      a textual expansion whose type at compile-time depends on the value
                      of DEBUG. If (DEBUG != 0), then sure, you can use the return value
                      of 'printj' (a.k.a. 'printf'). If (DEBUG == 0), then you have to
                      jump through many more hoops to get any useful information out of
                      that comma expression you've [presumably] got there.
                      [color=blue]
                      > NB2. You say "doesnt do anything". All the solutions offered so far
                      > do evaluate printj's arguments (eg. if you went: printj("%d", foo());
                      > then foo gets called). To prevent this you will have to use the
                      > normal method of #ifdef etc. around each printf.[/color]

                      No, there are a couple of hacks for this situation. One silly
                      and not-quite-foolproof one is

                      #ifndef DEBUG
                      #define printj (int)sizeof
                      #endif

                      This fails in the (hopefully unlikely) case of

                      printj("foo")[i++];

                      which should increment 'i', but with the current definition actually
                      does not. (Note that I've chosen to make 'printj' evaluate to type
                      'int', so that its type doesn't change when 'DEBUG' changes. That's
                      a style issue, I'm sure, and in real code I probably wouldn't even
                      do it.)

                      I was trying to compose a solution that would involve stringizing
                      the 'printj' "argument," but that really doesn't seem possible
                      (as long as we must keep the semantics that 'printj' be a drop-in
                      replacement for 'printf' in ordinary code).

                      -Arthur

                      Comment

                      • Jorge

                        #12
                        Re: Question about #define

                        On 1 Mar 2004 07:10:01 -0800, egrojorge@terra .es (Jorge Naxus) wrote:

                        Thanks to all the people who has helped me on these question, I have
                        learned a lot.

                        I dont have a C99 compiler (I am cross compiling), so I have used the
                        method proposed by John Cochran

                        #ifdef DEBUG
                        #define printj printf
                        #else
                        #define printj (void)
                        #endif

                        Although other possibilities you have pointed out would also be valid.

                        Acttually I dont change anything in my printf statements because these
                        are only for debugging purposes, so I dont mind if there are evaluated
                        or not.

                        I hate to read the C sources plenty of #ifdef around if statement, so
                        I think my code will be more beautiful now


                        Thanks!,

                        Jorge

                        Comment

                        • Michael Wojcik

                          #13
                          Re: Question about #define


                          In article <843a4f78.04030 11452.36d020d5@ posting.google. com>, oldwolf@inspire .net.nz (Old Wolf) writes:[color=blue][color=green]
                          > > I would like to write a macro like that:
                          > >
                          > > #ifdef DEBUG[/color]
                          >
                          > #define printj printf
                          >[color=green]
                          > > #else[/color]
                          >
                          > #define printj
                          >[color=green]
                          > > #endif
                          > >
                          > > So that printj behaves exactly like printf when DEBUG is true and
                          > > doesnt do anything when DEBUG is false.[/color]
                          >
                          > NB. Avoid using printj's return value
                          >
                          > NB2. You say "doesnt do anything". All the solutions offered so far
                          > do evaluate printj's arguments (eg. if you went: printj("%d", foo());
                          > then foo gets called). To prevent this you will have to use the
                          > normal method of #ifdef etc. around each printf.[/color]

                          I'd never use something like this, but how about one of:

                          #define printj 0 &&
                          #define printj 1 ||

                          for the non-DEBUG case, as a solution that doesn't evaluate the
                          arguments for subexpressions (not necessarily what's wanted, of
                          course) and evaluates to a known value (so the "return value"
                          is usable).

                          Or am I missing some obvious case where this construct fails
                          (as well as being ugly and obscuring the code, of course)?

                          --
                          Michael Wojcik michael.wojcik@ microfocus.com

                          Even though there may be some misguided critics of what we're trying
                          to do, I think we're on the wrong path. -- Reagan

                          Comment

                          • Lawrence V. Cipriani

                            #14
                            Re: Question about #define

                            In article <843a4f78.04030 11452.36d020d5@ posting.google. com>,
                            Old Wolf <oldwolf@inspir e.net.nz> wrote:[color=blue][color=green]
                            >> I would like to write a macro like that:
                            >>
                            >> #ifdef DEBUG
                            >> #define printj(...) printf(...)[/color]
                            >
                            >#define printj printf
                            >[color=green]
                            >> #else
                            >> #printj(...)[/color]
                            >
                            >#define printj
                            >[color=green]
                            >> #endif
                            >>
                            >> So that printj behaves exactly like printf when DEBUG is true and
                            >> doesnt do anything when DEBUG is false.[/color]
                            >
                            >NB. Avoid using printj's return value
                            >
                            >NB2. You say "doesnt do anything". All the solutions offered so far
                            >do evaluate printj's arguments (eg. if you went: printj("%d", foo());
                            >then foo gets called). To prevent this you will have to use the
                            >normal method of #ifdef etc. around each printf.[/color]

                            I've used this for more years than I care to admit:

                            #ifdef DEBUG
                            #define PRINT(arglist) fprintf arglist
                            #else
                            #define PRINT(arglist)
                            #endif

                            and then use it like:

                            PRINT((stderr, "foobar: %d\n", __LINE__));

                            Comment

                            • Derk Gwen

                              #15
                              Re: Question about #define

                              Jorge <terra@egrojorg e.es> wrote:
                              # On 1 Mar 2004 07:10:01 -0800, egrojorge@terra .es (Jorge Naxus) wrote:
                              #
                              # Thanks to all the people who has helped me on these question, I have
                              # learned a lot.
                              #
                              # I dont have a C99 compiler (I am cross compiling), so I have used the
                              # method proposed by John Cochran
                              #
                              # #ifdef DEBUG
                              # #define printj printf
                              # #else
                              # #define printj (void)
                              # #endif
                              #
                              # Although other possibilities you have pointed out would also be valid.

                              If printj is only used as statement you can use
                              #define printj if(0)

                              If the argument list side effect free, many compilers and any optimising
                              compiler will recognise the code is dead and elide it.

                              --
                              Derk Gwen http://derkgwen.250free.com/html/index.html
                              Raining down sulphur is like an endurance trial, man. Genocide is the
                              most exhausting activity one can engage in. Next to soccer.

                              Comment

                              Working...