|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
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) |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On 2008-05-29, Stefano Sabatini <stefano.sabatini@caos.org> 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) |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
> #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 |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
"Stefano Sabatini" <stefano.sabatini@caos.org> wrote in message news:slrng3so3t.87g.stefano.sabatini@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; } __________________________________________________ _____________ |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On 2008-05-29, Chris Thomasson <cristom@comcast.net> wrote:
> "Stefano Sabatini" <stefano.sabatini@caos.org> wrote in message > news:slrng3so3t.87g.stefano.sabatini@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) |
|
![]() |
| Outils de la discussion | |
|
|