Re: Preprocessor unique names



On Apr 11, 1:11 pm, Nate Eldredge <n...@xxxxxxxxxx> wrote:
"the.theorist" <the.theor...@xxxxxxxxx> writes:
I was implementing the traditional FOREACH macro, and noticed that in
C99 mode the usual int used for iteration must be declared prior to
the for loop. This means that my macro must declare a variable in an
outer scope. In order to avoid scope pollution, I'm wondering if there
is a way to coerce the preprocessor into creating unique names. Let me
demonstrate what I mean:

My macro:
#define FOREACH(p, set) \
int _i = 0; \
for (p = (set)->pset[_i]; \
_i<(set)->num; \
++_i) \

It's clear that in any scope I use this macro, a int variable by the
name _i will be created. Though I'm reasonably sure that this will not
be a problem if I use the macro multiple times in the same scope, or
choose to nest the FOREACH's, I'm still curious about how I could get
the preprocessor to generate a unique name for _i, so as to avoid any
possible aliasing.

Hm? I think you definitely have a problem if you write

FOREACH(p, set) foo(p);
FOREACH(p, set) bar(p);

The variable _i will be declared twice, which is definitely a syntax
error. Moreover, you should not be using names beginning with
underscores; they are reserved.

Anyway, your macro looks bogus, since p doesn't change during iteration
of the loop.

Good catch! That's a bug. I meant to reassign p to the next element of
(set)->pset.


One approach might be to make p be a pointer, and use it as the
iterator. E.g.

#define FOREACH(p, set) \
for (p = (set)->pset; p < (set)->pset + (set)->num; p++)

junk *p;
FOREACH(p, set) foo(*p);

I think I'll use this approach for two reasons:
(1) though I don't much care for pointer arithmetic, it's the way
thing are done in C, and it's straightforward enough for any other C
programmer (including myself a few months from now).
(2) it elegantly avoids the naming issue, and reduces the number of
variables in the code.


Then no temporary variable is needed.

My first thought was to use the __LINE__ directive and ##
concatenation. My plan was for the iteration variable to be named
_i610 if the FOREACH macro occured on line 610 in the source. For my
purposes, using line numbers will be unique enough. Unfortunately, the
preprocessor doesn't expand the __LINE__ and the variable name came
out as _i__LINE__. So my question for the group: Is there a way to get
the c preprocessor to generate unique names?

AFAIK, no.

.



Relevant Pages

  • Re: Unsure about Something
    ... I don't think there is any other way to do this (declare a local ... >>In each iteration you have declared a new variable with the name "a". ... > int n = i; ... > is re-created on each iteration of the loop. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Preprocessor unique names
    ... This means that my macro must declare a variable in an ... In order to avoid scope pollution, ... Anyway, your macro looks bogus, since p doesn't change during iteration ...
    (comp.lang.c)
  • Re: Unsure about Something
    ... In the second case you declare a *new* variable in each iteration. ... Because you've gone "out of scope" for the loop, ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: lisp idiom for processing each line in a file?
    ... But your point is taken -- if an iteration macro does choose ... to emit a LOOP, it should state so explicitly, e.g., add the ... Note that I already had some obvious qualms about declarations, ...
    (comp.lang.lisp)
  • Re: Unsure about Something
    ... you would be safe to declare your variable with the ... Note, however, that if you declare a variable in a Try block, it will not be ... > is re-created on each iteration of the loop. ...
    (microsoft.public.dotnet.languages.csharp)