C 用于对齐枚举和字符串的条件X宏

C 用于对齐枚举和字符串的条件X宏,c,conditional-statements,x-macros,C,Conditional Statements,X Macros,我有一个枚举列表: typedef enum { ENUM1, ENUM2, #if FLAG ENUM3, #endif } enum_var_t; 以及要对齐的字符串的对应列表: typedef struct { char[50] name; int val; } name_val_map_t name_val_map_t name_val_map_table[] = { {.name="string1", .val=ENUM1},

我有一个枚举列表:

typedef enum {
     ENUM1,
     ENUM2,
     #if FLAG
     ENUM3,
     #endif
} enum_var_t;
以及要对齐的字符串的对应列表:

typedef struct { char[50] name; int val; } name_val_map_t
name_val_map_t name_val_map_table[] = {
    {.name="string1", .val=ENUM1},
    {.name="string2", .val=ENUM2},
    #if FLAG
    {.name="string3", .val=ENUM3},
    #endif
};
标志是一个生成标志,为0或1。 我正在尝试使用X宏来根据以下答案对齐:

这会导致一个错误,即我向IF宏传递的参数多于声明的参数。我假定它将X(ENUM3,“string3”)内的逗号作为IF的参数分隔符。
我尝试用大括号封装X()调用,并从IF_IMPL中删除大括号,但也没有成功。如果我尝试使用…(和VA_ARGS)展开If()中的参数列表,则会出现预期的表达式错误。我试图避免使用def文件,因为这会使我的文件无法读取。像我尝试的一些解决方案对于避免代码复制和可读性来说是完美的。欢迎任何指点,谢谢

这似乎不必要地复杂。我只想这样做:

#if FLAG 
  #define var_list       \
  X(ENUM1, "string1")    \
  X(ENUM2, "string2")    \
  X(ENUM3, "string3")    
#else
  #define var_list       \
  X(ENUM1, "string1")    \
  X(ENUM2, "string2")    
#endif
完整示例:

#include <stdio.h>

#define FLAG 1

#if FLAG 
  #define var_list       \
  X(ENUM1, "string1")    \
  X(ENUM2, "string2")    \
  X(ENUM3, "string3")    
#else
  #define var_list       \
  X(ENUM1, "string1")    \
  X(ENUM2, "string2")    
#endif


typedef enum
{
  #define X(enum_var, str) enum_var,
    var_list
  #undef X

  ENUM_N
} enum_var_t;

typedef struct
{
  char name[50];
  int  val;
} name_val_map_t;

const name_val_map_t name_val_map_table[] = 
{
  #define X(enum_var, str) { .name = str, .val = enum_var },
    var_list
  #undef X
};

int main (void)
{
  for(size_t i=0; i<ENUM_N; i++)
  {
    printf("%d %s\n", name_val_map_table[i].val, name_val_map_table[i].name);
  }
}
#包括
#定义标志1
#如果旗
#定义变量列表\
X(枚举1,“字符串1”)\
X(枚举2,“字符串2”)\
X(枚举3,“字符串3”)
#否则
#定义变量列表\
X(枚举1,“字符串1”)\
X(枚举2,“字符串2”)
#恩迪夫
类型定义枚举
{
#定义X(枚举变量,str)枚举变量,
变量列表
#未定义X
枚举
}枚举变量;
类型定义结构
{
字符名[50];
int-val;
}名称、价值、地图;
const name_val_map_t name_val_map_表[]=
{
#定义X(enum_var,str){.name=str,.val=enum_var},
变量列表
#未定义X
};
内部主(空)
{
对于(尺寸i=0;i使用

测试:

//usr/local/bin/tcc-运行“$0”;退出$?
#包括
#定义标志3 1
#定义标志4 0
#定义标志5 1
typedef结构{char*name;int val;}name\u val\u map\t;
#定义IF(cond,foo)IF_IMPL(cond,foo)
#定义IF IMPL(cond,…)IF cond(u VA_ARGS)
#定义如果0(foo,…)
#定义如果_1(foo,…)foo,u VA_参数__
#定义变量列表\
X(枚举1,“字符串1”)\
X(枚举2,“字符串2”)\
IF(标志3,X(枚举3,字符串3”))\
IF(FLAG4,X(ENUM4,“string4”))\
如果(FLAG5,X(枚举5,“string5”))\
类型定义枚举{
#定义X(枚举值,str)枚举值,
变量列表
#未定义X
}枚举变量;
名称\u值\u映射\u名称\u值\u映射表[]={
#定义X(枚举值,名称){NAME,枚举值},
变量列表
#未定义X
{“哨兵值”,99}
};
内部主(空){
int x=0;
while(name_val_map_table[x].val!=99){
printf(“%i,%s\n”,name_val_map_table[x].val,name_val_map_table[x].name);
x++;}
返回0;
}
/*输出:
0,string1
1、2
2、3
3、5
*/
另一个选项是为每种情况手动创建IF_FLAGx(X(bla,bla))宏


另请参见:在MSVC bug的案例中。

什么是
X
?什么是
标志
?请在您的问题中包含一个说明问题的标记。
X
对任何事物都是一个非常坏的名称。当其他人看到它时,他们不会知道
X
的含义或它的作用,而不去挖掘它的实际实现“其他人”包括未来的你。谢谢,但我有几个条件,这会破坏我的代码。之前没有提到的道歉。还有很多“FLAG”的变体,所以有没有一种方法可以像我试图做的那样,在一行中做到这一点?
#include <stdio.h>

#define FLAG 1

#if FLAG 
  #define var_list       \
  X(ENUM1, "string1")    \
  X(ENUM2, "string2")    \
  X(ENUM3, "string3")    
#else
  #define var_list       \
  X(ENUM1, "string1")    \
  X(ENUM2, "string2")    
#endif


typedef enum
{
  #define X(enum_var, str) enum_var,
    var_list
  #undef X

  ENUM_N
} enum_var_t;

typedef struct
{
  char name[50];
  int  val;
} name_val_map_t;

const name_val_map_t name_val_map_table[] = 
{
  #define X(enum_var, str) { .name = str, .val = enum_var },
    var_list
  #undef X
};

int main (void)
{
  for(size_t i=0; i<ENUM_N; i++)
  {
    printf("%d %s\n", name_val_map_table[i].val, name_val_map_table[i].name);
  }
}
#define IF(cond, foo) IF_IMPL(cond, foo)
#define IF_IMPL(cond, ...) IF_ ## cond(__VA_ARGS__)
#define IF_0(foo, ...)
#define IF_1(foo, ...) foo, __VA_ARGS__
//usr/local/bin/tcc -run "$0"; exit $?
#include <stdio.h>

#define FLAG3 1
#define FLAG4 0
#define FLAG5 1

typedef struct { char *name; int val; } name_val_map_t;

#define IF(cond, foo) IF_IMPL(cond, foo)
#define IF_IMPL(cond, ...) IF_ ## cond(__VA_ARGS__)
#define IF_0(foo, ...)
#define IF_1(foo, ...) foo, __VA_ARGS__

#define var_list               \
X(ENUM1, "string1")            \
X(ENUM2, "string2")            \
IF(FLAG3, X(ENUM3, "string3")) \
IF(FLAG4, X(ENUM4, "string4")) \
IF(FLAG5, X(ENUM5, "string5")) \

typedef enum {
#define X(ENUMVAL, str) ENUMVAL,
    var_list
#undef X
} enum_var_t;

name_val_map_t name_val_map_table[] = {
#define X(ENUMVAL, NAME) { NAME, ENUMVAL },
    var_list
#undef X
    { "sentinel value", 99 }
};

int main(void){
    int x =0;
    while(name_val_map_table[x].val != 99){
        printf("%i, %s\n", name_val_map_table[x].val, name_val_map_table[x].name);
    x++;}
    return 0;
}

/* output:
    0, string1
    1, string2
    2, string3
    3, string5
*/