我想在switch / case语句中使用(const)struct成员作为选择器。问题是我得到一个" case表达式不是常数"或"非法持续表达"。这是一个简短的例子
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct _myStruct
{
unsigned int value_;
unsigned int index_;
} myStruct;
#define VALUE_0 0
const unsigned int VALUE_1 = 1;
const myStruct VALUE_2 = {2, 0};
int main()
{
srand((unsigned int)time(0));
switch(rand()%4)
{
case VALUE_0:
printf("Value is 0\n");
break;
case VALUE_1:
printf("Value is 1\n");
break;
case VALUE_2.value_:
printf("Value is 2\n");
break;
case 3:
printf("Value is 3\n");
break;
}
return 0;
}
case VALUE_2.value_
选项会生成编译器错误。顺便说一句,VALUE_2确实是一个常数。
我正在使用ANSI C.无论如何,C ++会产生同样的错误。
任何提示?
答案 0 :(得分:1)
在 C 中,const
- 限定变量的意思是“内存中只读对象”,但它不被视为整数常量表达式。
粗略地说,整数常量表达式是一个仅包含文字整数常量作为操作数的表达式。
特别是,扩展为整数字面的#define
- d常量在此处是有效的常量。
case
标签需要整数常量表达式,而不是变量。 const
限定符没有任何区别,不允许使用这种对象。
答案 1 :(得分:1)
简而言之,const
并不意味着“常量表达”(const
关键字有点令人困惑IMO)。确切地说,
C11 6.8.4.2 p.2(emph.mine)
每个案例标签的表达式应为整数常量表达式 [...]
所以,问题是,整数常量表达式是什么; C11在6.6中解决了这个问题:
说明(第2页)
常量表达式可以在转换期间而不是运行时进行评估,因此可以在常量可能的任何位置使用。
约束部分(第3/4页)继续:
常量表达式不应包含赋值,递增,递减,函数调用或逗号运算符,除非它们包含在未评估的子表达式中.15)
每个常量表达式应计算为其类型的可表示值范围内的常量。
脚注:
115)通常不评估sizeof或_Alignof运算符的操作数(6.5.3.4)。
语义(第5/6页)
在多个上下文中需要一个求值为常量的表达式。 [...]整数常量表达式应具有整数类型,只能具有整数常量的操作数,枚举常量,字符常量,
sizeof
表达式,其结果为整数常量,_Alignof
表达式,以及浮动常量,是转换的直接操作数。整数常量表达式中的转换运算符只能将算术类型转换为整数类型,除非作为sizeof
或_Alignof
运算符的操作数的一部分。 [EMPH。我的,省略脚注116和117]
强调的允许操作数列表不包含变量(至少一般情况下,sizeof VALUE_2
都可以),无论它们是const
- 是否合格(你提到过C ++)你的问题;如果你有兴趣,看看C ++ 11的constexpr
)。
和(同上,第10页)
实现可以接受其他形式的常量表达式。
我引用了C11; C99基本相同(但没有_Alignof
运算符),具有相同的部分。
HTH