切换错误::不能出现在常量表达式中

时间:2010-09-29 15:20:18

标签: c++ compiler-errors switch-statement

这是一个奇怪的...

我正在玩一些减压算法。在找到char buffer[]中的停止位之前,我没有经过buffer[i]并循环,而是尝试使用一些位掩码技术,但是使用字符。

我有以下示例:

// In a *.h file  
const char ch = '\x81';  
// To avoid Endianess  
union CharUInt  
{  
    char sz[4];  
    unsigned int u;  
};  
// Legal because char[] is declared before uint32 in the union  
const CharUInt Mask1 = {'\x81', '\x0', '\x0', '\x81'};  
const CharUInt Mask2 = {'\x0', '\x81', '\x81', '\x0'};  
// Proxy / Auxillary uint32 as usimg Mask2.u in the switch blocked produced the same errors  
const unsigned int uMask1 = Mask1.u;  
const unsigned int uMask2 = Mask2.u;  
const unsigned int uMask_ = (uMask1 & uMask2);  
// buf is always long enough  
bool Foo(char buf[])  
{  
    const CharUInt Type = {buf[0], buf[1], buf[2], buf[3]};  
    unsigned int uType = (Type.u & uMask_);  
    switch(uType)  
    {  
    case uMask1:  
        // do stuff  
    case uMask2:    
        // do more stuff  
        return true;  
        break;  
    default:  
        // do different stuff  
        return false;  
        break;  
    }  
};  

不考虑union内容的语法(实际代码编译运行正常)并且不考虑Foo的函数返回是否漂亮,我得到了 'uMask1' cannot appear in a constant-expression
如果使用工会本身,我会得到 'Mask1' cannot appear in a constant-expression
'.' cannot appear in a constant-expression
当然,错误也适用于uMask2和Mask2.u

我错过了什么?

提前致谢

2 个答案:

答案 0 :(得分:6)

混淆来自于const和const是两个。

switch语句中的case需要'常量表达式'。或者换句话说:编译器可以在编译时“计算”的表达式。 这可能是一个硬编码的数字(如42),或者之前已经定义为数字的东西(使用#define)。

编译器也使用Const,其含义是“一旦此变量具有值,它将不再更改”。例如。在以下代码中:

void myFunction (const int value)
{
...
}

值将是const。我将无法更改const的值,但这并不会使它成为编译器的“常量表达式”。

在你的情况下,uMask1是const(不能再改变它)但不是常量表达式。

答案 1 :(得分:1)

case条件表达式必须是整数类型,或者可以转换为整数类型,并且必须是const。

6.4.2 [stmt.switch]

  

条件应是完整的   类型,枚举类型或类   单个转换的类型   功能整体或枚举   类型存在(12.3)。如果条件   是类型,条件是   通过调用该转换进行转换   功能,以及结果   使用转换代替   其余的原始条件   这部分。整体促销   执行。内的任何陈述   可以标记switch语句   带有一个或多个案例标签   如下:

     

case constant-expression:

     

其中常量表达式应为   一个整数常数表达式。该   积分常数表达式(5.19)是   隐式转换为升级版   开关条件的类型。没有两个   案例常数相同   开关后应具有相同的值   转换为推广类型   切换条件。

您的表达式不是常量表达式,即使变量本身是const,因此您无法打开它。您需要使用if

你还有另外一个问题:

您创建了union

union CharUInt  
{  
    char sz[4];  
    unsigned int u;  
};

...然后你初始化该联盟的sz成员,

static const CharUInt Mask1 = {'\x81', '\x0', '\x0', '\x81'};  

...然后您访问该联盟的u成员。

static const unsigned int uMask1 = Mask1.u;  

根据标准,这会引起不确定的行为。在标准的语言中,工会的2名成员不能同时处于活动状态。意思是你不能像施法者那样对待一个联盟。