在switch / case语句中使用const struct成员

时间:2014-07-18 10:29:15

标签: c struct switch-statement

我想在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 ++会产生同样的错误。

任何提示?

2 个答案:

答案 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