f



Q: C macro's for lvalue statements ? Any C marco Guru's out there ?

Hi everybody,

I've got a problem implementing some macros that would make my code much
more readable.

The idea:
I have a set of macros that create variable names depending of the content
of some other define.

An example (of how it should look like in the end):

// ---------------  cut
#define BASE_NAME module1

// the macro(s) which I need help for :-)
#define MAKE_VARNAME2(base, var,val) int var#_#base = val
#define MAKE_VARNAME(var, val) MAKE_VARNAME2(BASE_NAME, var, val)

// the usage example
MAKE_VARNAME(status, 0);
// ---------------  cut

which should expand to

int status_module1 = 0;

I know, with the macro above this doesn't work so far, but is there a way to
generate lvalue names (like variable names) with C macros (like in the
example above) ?
The main problem is, that any string processing in macros generate real
strings (with  ""around) and the compiler doesn't accept them as lvalue -
and now I am unfortunetly out of ideas.

So it would be very helpful if there's any C macro guru out there who could
help m with this problem.

And by the way: Is there a way to #define anything within a #define ?
// ---------------  cut
#define TEST1(x) #define VARNAME x
// ---------------  cut

Thank you for your help/ideas.

Gregor




0
logical (3)
6/28/2004 6:37:22 PM
comp.unix.programmer 10848 articles. 0 followers. kokososo56 (350) is leader. Post Follow

5 Replies
1447 Views

Similar Articles

[PageSpeed] 12

"Gregor Copoix" <logical@xeption.de> writes:

> Hi everybody,
>
> I've got a problem implementing some macros that would make my code much
> more readable.
>
> The idea:
> I have a set of macros that create variable names depending of the content
> of some other define.
>
> An example (of how it should look like in the end):
>
> // ---------------  cut
> #define BASE_NAME module1
>
> // the macro(s) which I need help for :-)
> #define MAKE_VARNAME2(base, var,val) int var#_#base = val
> #define MAKE_VARNAME(var, val) MAKE_VARNAME2(BASE_NAME, var, val)
>
> // the usage example
> MAKE_VARNAME(status, 0);
> // ---------------  cut
>
> which should expand to
>
> int status_module1 = 0;
>
> I know, with the macro above this doesn't work so far, but is there a way to
> generate lvalue names (like variable names) with C macros (like in the
> example above) ?
> The main problem is, that any string processing in macros generate real
> strings (with  ""around) and the compiler doesn't accept them as lvalue -
> and now I am unfortunetly out of ideas.

You need to use the token merging operator (##) rather than stringification
operator (#), like this:

#define MAKE_VARNAME2(base, var,val) int var##_##base = val

> So it would be very helpful if there's any C macro guru out there who could
> help m with this problem.
>
> And by the way: Is there a way to #define anything within a #define ?

No.

-- 
M�ns Rullg�rd
mru@kth.se
0
iso
6/28/2004 11:18:54 AM
"Gregor Copoix" <logical@xeption.de> writes:

>> > I have a set of macros that create variable names depending of the content
>> > of some other define.
>> > An example (of how it should look like in the end):
>> > // ---------------  cut
>> > #define BASE_NAME module1
>> > // the macro(s) which I need help for :-)
>> > #define MAKE_VARNAME2(base, var,val) int var#_#base = val
>> > #define MAKE_VARNAME(var, val) MAKE_VARNAME2(BASE_NAME, var, val)
>> > // the usage example
>> > MAKE_VARNAME(status, 0);
>> > // ---------------  cut
>> >
>> > which should expand to
>> > int status_module1 = 0;
>
>> You need to use the token merging operator (##) rather than stringification
>> operator (#), like this:
>
>> #define MAKE_VARNAME2(base, var,val) int var##_##base = val
>
> But this results still in an lvalue error as the concaternated text is a
> string for the preprocessor.
> int "var_module1" = 0;
> and results in an compiler error.
> I tried both # and ##.

Then your bug is somewhere else.  It should work with ##.

-- 
M�ns Rullg�rd
mru@kth.se
0
iso
6/28/2004 1:13:10 PM
Gregor Copoix wrote:

> > You need to use the token merging operator (##) rather than
> stringification
> > operator (#), like this:
>
> > #define MAKE_VARNAME2(base, var,val) int var##_##base = val
>
> But this results still in an lvalue error as the concaternated text is a
> string for the preprocessor.
> int "var_module1" = 0;
> and results in an compiler error.
> I tried both # and ##.

For all the newsgroups you picked, was news:comp.lang.c completely out of
the question?

Here's my favorite example of token pasting creating an identifier:

    #define TEST_(suite, target)            \
        struct suite##target:  public suite \
        { void runCase(); }                 \
        a##suite##target;                   \
        void suite##target::runCase()

You did something wrong. Only # can create a string.

-- 
  Phlip
  http://industrialxp.org/community/bin/view/Main/TestFirstUserInterfaces


0
Phlip
6/28/2004 3:36:24 PM
> > I have a set of macros that create variable names depending of the
content
> > of some other define.
> > An example (of how it should look like in the end):
> > // ---------------  cut
> > #define BASE_NAME module1
> > // the macro(s) which I need help for :-)
> > #define MAKE_VARNAME2(base, var,val) int var#_#base = val
> > #define MAKE_VARNAME(var, val) MAKE_VARNAME2(BASE_NAME, var, val)
> > // the usage example
> > MAKE_VARNAME(status, 0);
> > // ---------------  cut
> >
> > which should expand to
> > int status_module1 = 0;

> You need to use the token merging operator (##) rather than
stringification
> operator (#), like this:

> #define MAKE_VARNAME2(base, var,val) int var##_##base = val

But this results still in an lvalue error as the concaternated text is a
string for the preprocessor.
int "var_module1" = 0;
and results in an compiler error.
I tried both # and ##.


Gregor


0
Gregor
6/28/2004 8:39:12 PM
"M�ns Rullg�rd" <mru@kth.se> wrote in message
news:yw1xfz8fu8pl.fsf@kth.se...
> "Gregor Copoix" <logical@xeption.de> writes:
>
> >> > I have a set of macros that create variable names depending of the
content
> >> > of some other define.
> >> > An example (of how it should look like in the end):
> >> > // ---------------  cut
> >> > #define BASE_NAME module1
> >> > // the macro(s) which I need help for :-)
> >> > #define MAKE_VARNAME2(base, var,val) int var#_#base = val
> >> > #define MAKE_VARNAME(var, val) MAKE_VARNAME2(BASE_NAME, var, val)
> >> > // the usage example
> >> > MAKE_VARNAME(status, 0);
> >> > // ---------------  cut
> >> >
> >> > which should expand to
> >> > int status_module1 = 0;
> >
> >> You need to use the token merging operator (##) rather than
stringification
> >> operator (#), like this:
> >
> >> #define MAKE_VARNAME2(base, var,val) int var##_##base = val
> >
> > But this results still in an lvalue error as the concaternated text is a
> > string for the preprocessor.
> > int "var_module1" = 0;
> > and results in an compiler error.
> > I tried both # and ##.
>
> Then your bug is somewhere else.  It should work with ##.
>
> -- 
> M�ns Rullg�rd
> mru@kth.se


Most compilers have an option to run just the preprocessor - for gcc it's
the -E switch. Try looking at the generated code and you'll have more chance
of figuring out what's going on.

You'll find that using '##' as suggested doesn't work - it generates

int status_BASE_NAME = 0;

You need another level of indirection to substitute the BASE_NAME text. Try:

#define BASE_NAME module1
#define PASTE3(a,b,c) a##b##c
#define MAKE_VARNAME2(base,var,val) int PASTE3(var,_,base) = val
#define MAKE_VARNAME(var,val) MAKE_VARNAME2(BASE_NAME,var,val)
MAKE_VARNAME(status, 0);

--
Roger


0
Roger
6/29/2004 10:10:33 PM
Reply: