【发布时间】:2013-01-08 16:07:12
【问题描述】:
我有以下代码
#define SWITCH(S) char *_S = S; if (0)
#define CASE(S) } else if (strcmp(_S, S) == 0) {switch(1) { case 1
#define BREAK }
#define DEFAULT } else {switch(1) { case 1
int main()
{
char buf[256];
printf("\nString - Enter your string: ");
scanf ("%s", buf);
SWITCH (buf) {
CASE ("abcdef"):
printf ("B1!\n");
BREAK;
CASE ("ghijkl"):
printf ("C1!\n");
BREAK;
DEFAULT:
printf ("D1!\n");
BREAK;
}
}
如果我用gcc -E生成预处理器代码,我会得到以下代码
int main()
{
char buf[256];
printf("\nString - Enter your string: ");
scanf ("%s", buf);
char *_S = buf;
if (0) {
} else if (strcmp(_S, "abcdef") == 0) {switch(1) { case 1:
printf ("B1!\n");
};
} else if (strcmp(_S, "ghijkl") == 0) {switch(1) { case 1:
printf ("C1!\n");
};
} else {switch(1) { case 1:
printf ("D1!\n");
};
}
}
但是对于一些在代码中间定义char *_S = buf;的gcc是不受欢迎的,可能会产生编译错误
如何在我的宏中解决这个问题?
请不要建议将char *_S 定义为全局(在main 之外)
【问题讨论】:
-
您希望宏生成什么?为什么
char *_S = buf;会出错?你的意思是如果_S已经定义了吗?正如 unwind 所建议的,最好的方法是摆脱宏。 -
它必须在一个块的开头,不一定是一个函数。正如 unwind 的回答中指出的那样,通过引入
SWITCH_END将{添加到SWITCH和另一个} -
这些宏可能会在调试会话中的某个时候回来咬你。这就是我尽可能避免使用宏的原因。您看到的代码与调试器看到的代码不同。
-
鉴于您的 SWITCH 控制结构当前具有的有趣限制(在每个块中只能使用一次;必须在每个案例上都有一个 BREAK 以防止失败,特别是因此没有连续案例共享代码;使用保留名称),我不认为再有一个有趣的限制会使它更难使用。在每次使用它的整个过程中添加一个额外的块,例如
{ SWITCH(S) { ... } }。 -
天哪,这太可怕了:(