470,864 Members | 2,023 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,864 developers. It's quick & easy.

Preprocessor directive including another one

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)
Jun 27 '08 #1
4 1959
On 2008-05-29, Stefano Sabatini <st**************@caos.orgwrote:
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)
Jun 27 '08 #2
Dan
#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
Jun 27 '08 #3

"Stefano Sabatini" <st**************@caos.orgwrote in message
news:sl*****************************@geppetto.reil abs.com...
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

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);
getchar();
return 0;
}

__________________________________________________ _____________

Jun 27 '08 #4
On 2008-05-29, Chris Thomasson <cr*****@comcast.netwrote:
"Stefano Sabatini" <st**************@caos.orgwrote in message
news:sl*****************************@geppetto.reil abs.com...
>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)
Jun 27 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

16 posts views Thread by Trying_Harder | last post: by
6 posts views Thread by olivier.grant | last post: by
31 posts views Thread by Sam of California | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.