2

I am trying to use unique variable names every time my macro is expanded, I cannot come up with a solution

I have code something like this

#define _each(results,arr,i,v, f)\
  for (i=0;i<len(arr);i++){\
    v = arr[i];\
    f\
  }

I'd love to assign a unique variable name to I and V.

So when they are expanded i get

for(i1=0;i<len(arr);i++){ // first expansion
  v = arr[i1];
  // dostuff
}
for(i2=0;i<len(arr);i++){
  v = arr[i2];
  // do stuff
}

I've tried __Counter__ but i cant figure out how to reuse the variable

#define m(var1,var2) {\  // example calling use m(i,v)
  var1 ##__COUNTER__ ;\  // prints i1 
  row = array[var1];\    // prints i, need i1
  row = array[var1 ##__COUNTER__##]; // prints i2.. i need i1

If that makes sense..

I need to increment the variable names because i have one case where I nest the macro!

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
boredguy
  • 23
  • 4
  • Since `i` and `v` are arguments to the macro, just use different names each time you use it. So you could call it nested like: `_each(results, arr, i, v_i, _each(results, arr, j, v_j))` – Chris Dodd Jun 26 '15 at 21:17

2 Answers2

2

You can use __LINE__ instead of the (non-standard) __COUNTER__. __LINE__ is the current line number in the source file of the original text (not the macro replacement text). So it doesn't change during the expansion of a macro, and it will be different for each macro expansion provided:

  • You never expand the macro twice in the same source code line
  • You don't try this trick from two different source files.
rici
  • 234,347
  • 28
  • 237
  • 341
  • hey thanks! this is a really good idea. this might be enough. if nobody else can give an answer i think this is it – boredguy Jun 27 '15 at 10:25
1

Unless your real-world use case is far more complex than your example, there is no need for you to use unique variable names.

Keep it simple! Just define them as local names within a block:

#define foreach(results, array, len, function) \
    { \
        int i; \
    \
        for (i = 0; i < len; i++) { \
            unsigned int v; \
    \
            v = array[i]; \
            v = function(v); \
            results[i] = v; \
        } \
    }

In C every block effectively gets its own region of stack for those more locally scoped variables defined within it and so you can have as many i and v variables as you need -- one set for every expansion of your macro.

Greg A. Woods
  • 2,663
  • 29
  • 26
  • it is :/ ... nested for loops abound! – boredguy Jun 26 '15 at 22:26
  • Even so, you can probably still use scoping to protect the local variables, though you may have to disable/ignore some silly warnings from some compilers. Perhaps though you'd be better off writing a proper code generator (e.g. in AWK, or Python, or ...) rather than abusing the preprocessor, and relying on such a very non-standard feature. – Greg A. Woods Jun 27 '15 at 01:40
  • If you _really_ want to use `__COUNTER__` though, it shouldn't be that difficult. Perhaps you can get a clue from: http://stackoverflow.com/questions/652815/has-anyone-ever-had-a-use-for-the-counter-pre-processor-macro – Greg A. Woods Jun 27 '15 at 01:40