Preprocessor directive including another one

Discussion in 'C Programming' started by Stefano Sabatini, May 29, 2008.

  1. Hi all C speakers,

    I would like to implement a macro which sets a field in a struct only
    if a certain preprocessor symbol has been defined.

    That is how one would naively implement this:
    ---------------------------------8<-------------------------------
    #include <stdio.h>
    #include <stdlib.h>

    typedef struct thing {
    int bar;
    int foo;
    } Thing;

    #ifndef CONFIG_NOFOO
    #define REGISTER_FOO(foo_) \
    .foo = foo_ \
    #endif

    Thing thing1 = {
    .bar= 1,
    REGISTER_FOO(42),
    };

    void thing_print(Thing *t)
    {
    printf("bar: %d\n", t->bar);
    printf("foo: %d\n", t->foo);
    }

    int main(void)
    {
    thing_print(&thing1);
    exit(0);
    }
    ---------------------------------8<-------------------------------

    And this is the (obvious) error message I got when compiling it:
    gcc -I/home/stefano/include/ -g -pg -I/home/stefano/include/ -L/home/stefano/lib recmacro.c -o recmacro
    recmacro.c:12:2: error: '#' is not followed by a macro parameter
    recmacro.c:16: error: initializer element is not constant
    recmacro.c:16: error: (near initialization for ‘thing1.foo’)
    recmacro.c:9:1: error: unterminated #ifndef
    make: *** [recmacro] Error 1

    So I wonder if there is some way to escape the '#' sign, also if this
    is possible will the preprocessor expand again the result of the
    first expansion?

    If this is not the right approach to implement this, can you suggest a
    valid one?

    Many thanks in advance, regards.
    --
    Stefano Sabatini
    Linux user number 337176 (see http://counter.li.org)
    Stefano Sabatini, May 29, 2008
    #1
    1. Advertising

  2. On 2008-05-29, Stefano Sabatini <> wrote:
    > Hi all C speakers,
    >
    > I would like to implement a macro which sets a field in a struct only
    > if a certain preprocessor symbol has been defined.
    >
    > That is how one would naively implement this:
    > ---------------------------------8<-------------------------------
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > typedef struct thing {
    > int bar;
    > int foo;
    > } Thing;
    >
    > #ifndef CONFIG_NOFOO
    > #define REGISTER_FOO(foo_) \
    > .foo = foo_ \
    > #endif


    Well, I really meant:

    #define REGISTER_FOO(foo_) \
    #ifndef CONFIG_NOFOO \
    .foo = foo_ \
    #endif

    >
    > Thing thing1 = {
    > .bar= 1,
    > REGISTER_FOO(42),
    > };
    >
    > void thing_print(Thing *t)
    > {
    > printf("bar: %d\n", t->bar);
    > printf("foo: %d\n", t->foo);
    > }
    >
    > int main(void)
    > {
    > thing_print(&thing1);
    > exit(0);
    > }
    > ---------------------------------8<-------------------------------
    >
    > And this is the (obvious) error message I got when compiling it:
    > gcc -I/home/stefano/include/ -g -pg -I/home/stefano/include/ -L/home/stefano/lib recmacro.c -o recmacro
    > recmacro.c:12:2: error: '#' is not followed by a macro parameter
    > recmacro.c:16: error: initializer element is not constant
    > recmacro.c:16: error: (near initialization for ‘thing1.foo’)
    > recmacro.c:9:1: error: unterminated #ifndef
    > make: *** [recmacro] Error 1
    >
    > So I wonder if there is some way to escape the '#' sign, also if this
    > is possible will the preprocessor expand again the result of the
    > first expansion?
    >
    > If this is not the right approach to implement this, can you suggest a
    > valid one?
    >
    > Many thanks in advance, regards.

    --
    Stefano Sabatini
    Linux user number 337176 (see http://counter.li.org)
    Stefano Sabatini, May 29, 2008
    #2
    1. Advertising

  3. Stefano Sabatini

    Dan Guest


    > #ifndef CONFIG_NOFOO
    > #define REGISTER_FOO(foo_) \
    > .foo = foo_ \
    > #endif


    #ifndef CONFIG_NOFOO
    #define REGISTER_FOO(x) foo = x;
    #else
    #define REGISTER_FOO(x)
    #endif
    Dan, May 29, 2008
    #3
  4. On 2008-05-29, Chris Thomasson <> wrote:
    > "Stefano Sabatini" <> wrote in message
    > news:...
    >> Hi all C speakers,
    >>
    >> I would like to implement a macro which sets a field in a struct only
    >> if a certain preprocessor symbol has been defined.
    >>

    > [...]
    >
    > The following works for me in C99 mode:
    > _______________________________________________________________
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > typedef struct thing {
    > int bar;
    > int foo;
    > } Thing;
    >
    > #ifndef CONFIG_NOFOO
    > #define REGISTER_FOO(foo_) .foo = foo_
    > #else
    > #define REGISTER_FOO(foo_)
    > #endif


    Thanks Dan and Chris!

    This works fine (I just simplified the no-no logic of the macro and
    explicitely set the macro expansion when the CONFIG_NOFOO is expanded
    to avoind a ",," syntax error):

    --------------8<--------------------------------
    #include <stdio.h>
    #include <stdlib.h>

    typedef struct thing {
    int bar;
    int foo;
    } Thing;

    #define CONFIG_NOFOO

    #ifdef CONFIG_NOFOO
    #define REGISTER_FOO(foo_) .foo = NULL
    #else
    #define REGISTER_FOO(foo_) .foo = foo_
    #endif

    Thing thing1 = {
    .bar= 1,
    REGISTER_FOO(42),
    };

    void thing_print(Thing *t)
    {
    printf("bar: %d\n", t->bar);
    printf("foo: %d\n", t->foo);
    }

    int main(void)
    {
    thing_print(&thing1);
    return 0;
    }
    --------------8<--------------------------------

    Best regards
    --
    Stefano Sabatini
    Linux user number 337176 (see http://counter.li.org)
    Stefano Sabatini, May 29, 2008
    #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. Trying_Harder

    Preprocessor directive

    Trying_Harder, Oct 2, 2003, in forum: C Programming
    Replies:
    16
    Views:
    670
    Kevin Easton
    Oct 5, 2003
  2. Replies:
    3
    Views:
    518
    Default User
    Mar 13, 2007
  3. Replies:
    1
    Views:
    380
    Ian Collins
    Mar 13, 2007
  4. Replies:
    2
    Views:
    433
    Walter Roberson
    Nov 28, 2007
  5. Replies:
    5
    Views:
    474
    Joe Greer
    Jan 8, 2008
Loading...

Share This Page