【问题标题】:Is there a way to write a C preprocessor macro with variable args like this?有没有办法用这样的变量 args 编写 C 预处理器宏?
【发布时间】:2019-10-02 04:28:42
【问题描述】:

我想要一个可以转换它的 C 预处理器宏:

if (IN(node->type, BRANCH, CAPTURE_START, CAPTURE_END)) {
    ...
}

到这里:

if (node->type == BRANCH || node->type == CAPTURE_START || node->type == CAPTURE_END) {
    ...
}

这有点类似于 MySQL IN 运算符。有可能吗?

【问题讨论】:

  • 您是否只是在寻找简单的宏替换来检查给定值是否是这些选项中的任何一个?如果是这样,您可以只做#define IN(val, opt1, opt2, opt3) (val == opt1 || val == opt2 || val ==opt3)
  • 我想要那个,但有任意数量的选项。
  • 不具有任意。即使是计算宏参数,您也需要为每个参数计数编写一个或两个宏...

标签: c c-preprocessor


【解决方案1】:

CPP 不支持迭代参数列表。 “C”中最接近的结构将是 switch 语句,但它不会将自身引向

  switch (node->type ) {
      case V1:
      case V2:
      case V3:
          ...
   }

作为替代方案,您可以获得更符合“IN”测试的内容,使用 带有可变参数函数的函数。这是(1)必须知道类型和(2)会有一个特殊值(示例中为 LAST)来指示列表结尾的限制

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdarg.h>

#define LAST (-1)

bool in_int_set(int v, ...)
{
   va_list ap ;
   va_start(ap, v) ;
   for (;;) {                        // forever
        int s = va_arg(ap, int) ;
        if ( s == LAST ) return false ;
        if ( s == v ) return true ;
   } ;
}

void main(void) {
        printf("A=%d\n", in_int_set(5,      3, 5, 7, LAST)) ;
        printf("B=%d\n", in_int_set(5,      2, 4, 6, 8, 10, LAST)) ;
// From the question about
        if ( in_int_set(node->type,     BRANCH, CAPTURE_START, CAPTURE_END, LAST) ) {
            ...
        }
}

【讨论】:

    猜你喜欢
    • 2016-05-08
    • 1970-01-01
    • 2011-08-22
    • 2010-09-09
    • 2020-05-29
    • 2015-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多