2

i want to concatenate a lot of macros in order to pass them as parameter in a struck array. to be more specific i have this struct

static struct
{
 unsigned int num_irqs;
 volatile __int_handler *_int_line_handler_table;
}_int_handler_table[INTR_GROUPS];

and I want to pass as num_irqs parameter a series of macros

AVR32_INTC_NUM_IRQS_PER_GRP1

AVR32_INTC_NUM_IRQS_PER_GRP2
...

first I thought to use this code

for (int i=0;i<INTR_GROUPS;i++)
{
   _int_handler_table[i].num_irqs = TPASTE2(AVR32_INTC_NUM_IRQS_PER_GRP,i); 
}

but it takes the i as char and not the specific value each time. I saw also that there is a MREPEAT macro defined in the preprocessor.h but I do not understand how it is used from the examples.

Can anyone can explain the use of MREPEAT or another way to do the above.

unwind
  • 391,730
  • 64
  • 469
  • 606
arcanavk
  • 91
  • 1
  • 7
  • There is a great conversation ***[HERE](http://stackoverflow.com/questions/17132017/how-do-i-write-a-recursive-for-loop-repeat-macro-to-generate-c-code-with-the-c)*** that I believe touches on what you are trying to do. It includes using looping macros, in this example to generate code. (supports possibly what @unwind is suggesting in his answer: _in which case code-generation is a common solution_) – ryyker Sep 10 '15 at 13:55

2 Answers2

3

C doesn't work like that.

Macros are just text-replacement which happens att compile-time. You can't write code to construct a macro name, that doesn't make sense. The compiler is no longer around when your code runs.

You probably should just do it manually, unless the amount of code is very large (in which case code-generation is a common solution).

unwind
  • 391,730
  • 64
  • 469
  • 606
3

Keep in mind the preprocessor (which manipulates macros) runs before the compiler. It's meant to manipulate the final source code to be submitted to the compiler.

Hence, it has no idea of what value has a variable. For the preprocessor, i means i.

What you try to do is a bit complex, especially keeping in mind that preprocessor cannot generate preprocessor directives.

But it can generate constants. Speaking of which, for your use case, I would prefer to use a table of constants, such as :

const int AVR32_INTC_NUM_IRQS_PER_GRP[] = { 1, 2, 3, 4, 5 };

for (int i=0;i<INTR_GROUPS;i++)
{
   _int_handler_table[i].num_irqs = TPASTE2(AVR32_INTC_NUM_IRQS_PER_GRP[i]); 
}
Cyan
  • 13,248
  • 8
  • 43
  • 78
  • _...the preprocessor runs_ ***before*** _the compiler_? How does it do that exactly? – ryyker Sep 10 '15 at 13:42
  • Unless the size and signedness of the constants are important, consider using an array of enums instead. – Lundin Sep 10 '15 at 14:10
  • @rykker that's indeed why it's called a *pre*processor. Suggest reading this excellent doc : https://gcc.gnu.org/onlinedocs/cpp/ – Cyan Sep 10 '15 at 21:19