【问题标题】:C preprocessor macro multiple argumentsC 预处理器宏多参数
【发布时间】:2021-01-19 23:54:40
【问题描述】:

所以我有这个“检查”宏,它有两个参数:

#define check(reg, n) ((reg >> n) & 1U)

我有这个参数列表:

#define TEST_ARGS 10, 1

代码:

check(TEST_ARGS);

预期扩展:

((10 >> 1) & 1U)

真正的扩张:

((10, 1 >> ) & 1U)

如何为“check”宏定义多个参数以获得预期结果?

非常感谢。

【问题讨论】:

    标签: c c-preprocessor


    【解决方案1】:

    在顶级(非宏替换)输入中,宏调用参数列表在参数被宏扩展之前立即解析。 (必须如此,因为与 ### 宏运算符一起使用的宏参数没有展开,并且在检查替换体之前不知道。)

    但是,在替换正文中扫描宏之前,替换正文中的参数将替换为相应的参数(如果该参数未与 ### 一起使用,则这些参数将被宏扩展)。

    所以你可以通过添加一个间接级别来达到你想要的效果。但是,您可能希望使用可变参数宏,以防调用者使用显式逗号:

    #define CHECK(...) CHECK_(__VA_ARGS__)
    #define CHECK_(reg, n) ((reg >> n) & 1U)
    
    #define TEST_ARGS 10, 1
    CHECK(TEST_ARGS)
    

    测试:

    $ $ gcc -x c -E - <<<'#define CHECK(...) CHECK_(__VA_ARGS__)
    > #define CHECK_(reg, n) ((reg >> n) & 1U)
    > 
    > #define TEST_ARGS 10, 1
    > CHECK(TEST_ARGS)'
    # 1 "<stdin>"
    # 1 "<built-in>"
    # 1 "<command-line>"
    # 31 "<command-line>"
    # 1 "/usr/include/stdc-predef.h" 1 3 4
    # 32 "<command-line>" 2
    # 1 "<stdin>"
    
    
    
    
    ((10 >> 1) & 1U)
    

    【讨论】:

      【解决方案2】:

      简而言之,这个问题与 TEST_ARGS 被视为 check() 宏的第一个参数有关,并且不知何故,一个空参数被认为是编译器的第二个参数。 (在我尝试过的所有编译器上,如果缺少第二个参数,编译器会产生错误)。


      您需要一个间接级别以允许您的宏 TEST_ARGS 在传递给 check() 之前展开。

      例如:

      #define check2(...) check(__VA_ARGS__)
      

      然后,使用check2(TEST_ARGS)


      对于 MSVC,我必须做一些更复杂的事情:

      #define V_(...) __VA_ARGS__
      #define I_(M,...) V_(M(__VA_ARGS__))
      #define check2(...) I_(check, __VA_ARGS__)
      

      【讨论】:

      • 这很有帮助。我很笨,遇到了一个类似的问题,即 10,1 被评估为单个标记,而不是两个参数。
      【解决方案3】:

      预处理器进行文本替换(实际上它替换了标记)。所以如果

      #define check(reg, n) ((reg >> n) & 1U)
      #define TEST_ARGS 10, 1
      

      然后

      check(TEST_ARGS);
      

      被预处理为:

      check(10, 1,);  
      

      第一个参数是完整的令牌10,1,第二个是空的

      【讨论】:

      • 可以将其设为“check(10, 1);” ?
      • @malidu 干什么用的?
      猜你喜欢
      • 2020-02-09
      • 1970-01-01
      • 2015-05-08
      • 2012-07-22
      • 2013-03-14
      • 2011-01-26
      • 1970-01-01
      • 2012-05-12
      • 2021-02-03
      相关资源
      最近更新 更多