我非常清楚 switch
语句背后的机制以及为什么需要整数常量。我不明白的是为什么下面的 case
标签不被认为是整数常量。之后怎么样了?一个不存在的变量?任何人都可以分类吗? C 编译器真的需要这么笨吗?
struct my_struct {
const int my_int;
};
switch (4) {
case ((struct my_struct) { 4 }).my_int:
printf("Hey there!\n");
break;
}
当然……
error: case label does not reduce to an integer constant
case ((struct my_struct) { 4 }).my_int:
编辑以回答 Eugene 的评论:
What's you real use case? If it is an integer constant, why to make it so complicated?
我试图找到一个巧妙的 hack 来在两个字符的字符串之间切换,使用 union
而不是 struct
,如下例所示:
#include <stdio.h>
union my_union {
char my_char[sizeof(int)];
int my_int;
};
void clever_switch (const char * const my_input) {
switch (((union my_union *) my_input)->my_int) {
case ((union my_union) { "hi" }).my_int:
printf("You said hi!\n");
break;
case ((union my_union) { "no" }).my_int:
printf("Why not?\n");
break;
}
}
int main (int argc, char *argv[]) {
char my_string[sizeof(int)] = "hi";
clever_switch(my_string);
return 0;
}
…这当然不能编译。
在我的机器上 ((union my_union) { "hi"}).my_int
是 26984
而 ((union my_union) { "no"}).my_int
是 28526
。但是我不能自己写这些数字,因为它们取决于机器的字节序(所以显然我的机器是小字节序的)。但是编译器知道后者,并且在编译期间确切地知道 ((union my_union) { "no"}).my_int
将是什么数字。
烦人的是我可以已经做到了,但只是使用了一种非常晦涩(而且效率稍低)的语法。下面的例子编译得很好:
#include <stdio.h>
void clever_switch (const char * const my_input) {
#define TWO_LETTERS_UINT(FIRST_LETTER, SECOND_LETTER) ((unsigned int) ((FIRST_LETTER) << 8) | (SECOND_LETTER))
switch (TWO_LETTERS_UINT(my_input[0], my_input[1])) {
case TWO_LETTERS_UINT('h', 'i'):
printf("You said hi!\n");
break;
case TWO_LETTERS_UINT('n', 'o'):
printf("Why not?\n");
break;
}
#undef TWO_LETTERS_UINT
}
int main (int argc, char *argv[]) {
clever_switch("hi"); /* "You said hi!" */
clever_switch("no"); /* "Why not?" */
return 0;
}
所以问题仍然存在:C 编译器(或本例中的 C 标准)真的需要这么笨吗?
最佳答案
虽然表达式 ((struct my_struct) { 4 }).my_int
在运行时确实被评估为 4,但它不是常量。 switch-case 需要一个常量表达式。
我看到您已将 my_int
声明为 const
。但这仅意味着以后无法对其进行修改。这并不意味着表达式 ((struct my_struct) { 4 }).my_int
是常量。
如果你使用 if-statement
而不是 switch-case
,你会没事的。
if (((struct my_struct) { 4 }).my_int == 4) {
printf("Hey there!\n");
}
关于c - 开关盒 : case label does not reduce to an integer constant,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55580175/