如果我告诉你我想要实现以下代码:
static const uint8_t jump_table[] =
{
/* ' ' */ 1, 0, 0, /* '#' */ 4,
0, /* '%' */ 14, 0, /* '\''*/ 6,
...
...
/* 't' */ 27, /* 'u' */ 16, 0, 0,
/* 'x' */ 18, 0, /* 'z' */ 13
};
#define LABEL(Name) do_##Name
#define NOT_IN_JUMP_RANGE(Ch) ((Ch) < ' ' || (Ch) > 'z')
#define CHAR_CLASS(Ch) (jump_table[(INT_T) (Ch) - ' '])
#define REF(Name) &&do_##Name
#define JUMP(ChExpr, table) \
do \
{ \
const void *ptr; \
spec = (ChExpr); \
ptr = NOT_IN_JUMP_RANGE (spec) ? REF (form_unknown) \
: table[CHAR_CLASS (spec)]; \
goto *ptr; \
} while (0)
#define TABLE \
/* Step 0: at the beginning. */ \
static JUMP_TABLE_TYPE step0_jumps[30] = \
{ \
REF (form_unknown), \
REF (flag_space), /* for ' ' */ \
REF (flag_plus), /* for '+' */ \
REF (flag_minus), /* for '-' */ \
... \
REF (flag_i18n), /* for 'I' */ \
};
使用示例如下:
void usage_example_function(void)
{
do
{
TABLE;
/* Get current character in format string. */
JUMP (*++f, step0_jumps);
/* ' ' flag. */
LABEL (flag_space):
space = 1;
JUMP (*++f, step0_jumps);
...
...
} while (something)
}
您会告诉我,在任何合理的编程风格标准下,这是不可接受的,提交这样的代码很可能会带来更多的伤害而不是好处。
现在,glibc使用远比这个(上面代码摘自那里)更多的宏滥用来实现vfprintf,然而这段代码是如此多的编译程序的一部分,并被测试了那么多次,以至于让我觉得今天的(宏)编码标准缺乏正当性。
为什么这样的宏滥用是错误的?或者,如果这样的滥用是如此错误,为什么我们接受这样的
libc
实现?