使用 X 宏的嵌套 switch 语句

问题描述 投票:0回答:1
#define LIST_D1(val, mask, _lc, _UC, comment, parentDictId) \
    __BTN(val 1, mask ~0, _lc##cred_amazon_mws_token, _UC##CRED_AMAZON_MWS_TOKEN, comment N_("Amazon MWS Auth Token"), parentDictId 170) \
    __BTN(val 2, mask ~0, _lc##cred_git_token, _UC##CRED_GIT_TOKEN, comment N_("Git Token"), parentDictId 170) \
    /*end-of-list*/

#define LIST_D2(val, mask, _lc, _UC, comment, parentDictId) \
    __BTN(val 1, mask ~0, _lc##cred_amazon_mws_token, _UC##CRED_AMAZON_MWS_TOKEN, comment N_("Amazon MWS Auth Token"), parentDictId 172) \
    __BTN(val 2, mask ~0, _lc##cred_git_token, _UC##CRED_GIT_TOKEN, comment N_("Git Token"), parentDictId 172) \
    /*end-of-list*/

#define LIST_D3(val, mask, _lc, _UC, comment, parentDictId) \
    __BTN(val 1, mask ~0, _lc##aspp_cn, _UC##ASPP_CN, comment N_("China (CN)"), parentDictId 171) \
    __BTN(val 2, mask ~0, _lc##aspp_jp, _UC##ASPP_JP, comment N_("Japan (JP)"), parentDictId 171) \
    /*end-of-list*/
/* __BTN(val, mask, name, shortname, internal_name, comment) */
#define list_dicts \
    __BTN(172, 0, DICT_CRED, Credentials and Secrets, D1, N_("Credentials and Secrets"))    \
    __BTN(171, 0, DICT_EUPP, Passport - EU, D2, N_("Passport - EU"))                     \
    __BTN(170, 0, DICT_USDL, Drivers License (US), D2, N_("Drivers License U.S."))       \
    /* end of list */

static const char *get_name(int did, int id) {

    char *a;
    switch (did) {
#define __BTN(val, mask, name, shortname, internal_name, comment) \
      case val: \
          return #internal_name; \
          break;
          list_dicts
#undef __BTN
   }
   return NULL;
}
int main() {

    int id = 170;

    printf("I got: %s\n", get_name(id, 1));
    return 0;
}

通过上面的代码和 X 宏,我能够实现这一点,这与简单的 switch 语句配合得很好。这是

的输出

gcc代码.c -E

static const char *get_name(int did, int id) {

 char *a;
     switch (did) {
   case 172: return "D1"; break; case 171: return "D2"; break; case 170: return "D2"; break;

  }
 return ((void *)0)
           ;
}

我的目标是使用 X 宏创建类似的东西。我以前从未使用过 X 宏。我愿意更改原始宏定义以使这项工作正常进行。如果不是X-macros,如何有效地实现这一点?

 static const char *get_name(int did, int id) {

 char *a;
 switch (did) {
   case 172:
     /* LIST_D1 using #internal_name "D1" or parentDictId number 172 */
     switch (id) {
           case 1:
               return #comment;
           case 2:
               return #comment;
           
      } 
      break; 
   case 171:
     ...
     break; 
  case 170:
     ...
     break;
 }
 return NULL;
}
c switch-statement x-macros
1个回答
4
投票

我的目标是[扩展嵌套] Xmacros。

这是可以做到的,但是它会变得非常混乱,速度非常快。如果您想继续这样做,那么您将需要在不同列表中为 X 宏使用不同的名称。将这些宏的名称作为列表宏的参数接收也可能对您有益。这不仅允许您同时定义多个 X 宏并在同一代码中使用,而且还允许对它们进行不同的参数化(基于每个目标列表)。

我已经按照上述方式使用了 X 宏,但我不会给出示例,因为几乎可以肯定,您最好采取不同的做法。例如,您可以考虑

  • 将数据放入数组中并编写一个其行为由这些数组驱动的函数。或者

  • 编写一个单独的程序来为您生成所需的代码,而不是依赖于 C 预处理器。

© www.soinside.com 2019 - 2024. All rights reserved.