【问题标题】:Macro as a parameter to another macro宏作为另一个宏的参数
【发布时间】:2014-04-11 19:27:52
【问题描述】:

我正在尝试使用另一个预定义的宏将参数传递给宏 SETBIT,如下所示:

#define SETBIT(ADDRESS,BIT,N) {(N) ? (ADDRESS &= ~(1<<BIT)) : (ADDRESS |= (1<<BIT))}
#define DAC_SYNC PORTB,3,POS
SETBIT(DAC_SYNC);

但是我收到错误:

宏 SETBIT 需要 3 个参数,只有 1 个给定

有一个article 有以下建议:

为了防止算术运算的错误嵌套:#define foo (a,b)#define bar(x) lose((x))

但即使我仍然有错误。顺便说一句,阅读我指出的文章,我可以得出以下结论:预处理器扩展了所有出现的宏。但实际上看起来宏 #define DAC_SYNC PORTB,3,POS 没有被预处理器扩展。

谁能更清楚 GCC 的预处理器是如何工作的?

【问题讨论】:

    标签: c gcc macros c-preprocessor


    【解决方案1】:

    这行得通:

    #define SETBIT2(ADDRESS,BIT,N) ((N) ? (ADDRESS &= ~(1<<BIT)) : (ADDRESS |= (1<<BIT)))
    #define SETBIT(PARAMS) SETBIT2(PARAMS)
    #define PORTB 5
    #define POS 7
    #define DAC_SYNC PORTB,3,POS
    
    int main() {
      int a = SETBIT(DAC_SYNC);
      return 0;
    }
    

    【讨论】:

    • 成功了!!!但实际上我没有明白这一点:为什么这解决了问题?有没有关于这个主题的明确文章?
    • 我建议#define SETBIT(...) SETBIT2(__VA_ARGS__) -- 这样你可以使用扩展为 3 个参数的宏或直接使用 3 个参数调用 SETBIT
    • @RomanMatveev:它通过添加一个额外的间接来工作,该间接导致DAC_SYNC 宏在将参数解析为SETBIT2 之前被扩展。 C 宏扩展的工作原理是首先解析参数,然后扩展参数中的任何宏,然后将参数替换到正文中,然后重新扫描结果以获取更多要扩展的宏。顺序很重要!
    • 天啊!现在声明SETBIT(PORTA,2,0) 不起作用:(((((((
    【解决方案2】:

    为了完整起见,您链接到的同一手册还指出:

    您提供的参数数量必须与 宏定义中的参数。当宏展开时,每个 在其主体中使用参数被 对应的论点。

    因此,ooga 的示例很好地演示了宏扩展是如何递归工作的,首先扩展外部宏,然后扩展参数。

    【讨论】:

      猜你喜欢
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多