PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.c > Preprocessor directive including another one
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Preprocessor directive including another one

Réponse
 
LinkBack Outils de la discussion
Vieux 29/05/2008, 08h51   #1
Stefano Sabatini
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut 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)
  Réponse avec citation
Vieux 29/05/2008, 08h58   #2
Stefano Sabatini
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Preprocessor directive including another one

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)
  Réponse avec citation
Vieux 29/05/2008, 09h00   #3
Dan
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Preprocessor directive including another one


> #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


  Réponse avec citation
Vieux 29/05/2008, 09h07   #4
Chris Thomasson
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Preprocessor directive including another one


"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;
}

__________________________________________________ _____________

  Réponse avec citation
Vieux 29/05/2008, 09h26   #5
Stefano Sabatini
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Preprocessor directive including another one

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)
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 18h02.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,13672 seconds with 13 queries