【问题标题】:concatenate macros in c in a loop在循环中连接c中的宏
【发布时间】:2015-09-10 12:20:32
【问题描述】:

我想连接很多宏,以便将它们作为参数传递到一个被触发的数组中。更具体地说,我有这个结构

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

我想将一系列宏作为num_irqs 参数传递

AVR32_INTC_NUM_IRQS_PER_GRP1

AVR32_INTC_NUM_IRQS_PER_GRP2
...

首先我想使用这个代码

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

但它每次都将i 视为char 而不是具体值。我还看到 preprocessor.h 中定义了一个 MREPEAT 宏,但我不明白它是如何从示例中使用的。

任何人都可以解释MREPEAT的用法或其他方式来完成上述操作。

【问题讨论】:

  • 有一个很棒的对话 HERE,我相信它触及了你想要做的事情。它包括使用循环宏,在此示例中生成代码。 (可能支持@unwind 在他的回答中的建议:在这种情况下,代码生成是一种常见的解决方案

标签: c loops macros concatenation


【解决方案1】:

请记住,预处理器(操作宏)在编译器之前运行。它旨在操纵要提交给编译器的最终源代码。

因此,它不知道什么值有一个变量。对于预处理器,i 表示i

您尝试做的事情有点复杂,特别是要记住预处理器不能生成预处理器指令。

但它可以生成常量。 说到这,对于您的用例,我更喜欢使用常量表,例如:

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]); 
}

【讨论】:

  • ...预处理器运行 之前 编译器?它是如何做到这一点的?
  • 除非常量的大小和符号很重要,否则请考虑使用枚举数组。
  • @rykker 这就是它被称为 pre 处理器的原因。建议阅读这篇优秀的文档:gcc.gnu.org/onlinedocs/cpp
【解决方案2】:

C 不是那样工作的。

宏只是在编译时发生的文本替换。您不能编写代码来构造宏名称,这是没有意义的。当您的代码运行时,编译器不再存在。

您可能应该只手动完成,除非代码量非常大(在这种情况下,代码生成是一种常见的解决方案)。

【讨论】:

    猜你喜欢
    • 2014-12-06
    • 2016-03-04
    • 1970-01-01
    • 2017-08-18
    • 1970-01-01
    • 1970-01-01
    • 2015-03-29
    • 2019-04-14
    相关资源
    最近更新 更多