简体   繁体   English

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

[英]Switch error:: cannot appear in a constant-expression

this is a strange one... 这是一个奇怪的...

I am playing with some decompression algo. 我正在玩一些减压算法。 Instead of going through the char buffer[] and looping until a stop-bit in buffer[i] is found, I am trying use some bit-mask techniques but with chars. 而不是通过char buffer[]并循环直到找到buffer[i]的停止位,我尝试使用一些位掩码技术,但使用字符。

I have the following example: 我有以下示例:

// 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;  
    }  
};  

Without considering the syntax of the union stuff (the actual code compiles run fine for that) and without considering whether the function-return for Foo is pretty, I get 不考虑union内容的语法(实际代码编译运行正常)并且不考虑Foo的函数返回是否相当,我得到
'uMask1' cannot appear in a constant-expression
and if the unions themselves are used, I get 如果工会本身被使用,我得到
'Mask1' cannot appear in a constant-expression
'.' cannot appear in a constant-expression
and of course the errors also apply for uMask2 and Mask2.u 当然,错误也适用于uMask2和Mask2.u

What am I missing? 我错过了什么?

Thanks in advance 提前致谢

The confusion comes from the fact that const and const are two. 混淆来自const和const是两个的事实。

The case's in the switch statement need 'constant expressions'. switch语句中的case需要'常量表达式'。 Or in other words: expressions that can be 'calculated' by the compiler, at compile-time. 或者换句话说:编译器可以在编译时“计算”的表达式。 This could be a hard-coded number (like 42), or something that has been defined before as a number (using #define). 这可能是一个硬编码的数字(如42),或者之前已经定义为数字的东西(使用#define)。

Const is also used by the compiler with the meaning "once this variable has a value, it won't change anymore". 编译器也使用Const,其含义是“一旦此变量具有值,它将不再更改”。 Eg in the following code: 例如,在以下代码中:

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

value will be const. 值将是常量。 I will not be able to change the value of const, but this does not make it a 'constant expression' for the compiler. 我将无法更改const的值,但这并不会使它成为编译器的“常量表达式”。

In your case, uMask1 is const (can't change it anymore) but not a constant expression. 在你的情况下,uMask1是const(不能再改变它)但不是常量表达式。

case condition expression must be of integral type, or convertible to integral type, and must be const. case condition表达式必须是整数类型,或者可以转换为整数类型,并且必须是const。

6.4.2 [stmt.switch] 6.4.2 [stmt.switch]

The condition shall be of integral type, enumeration type, or of a class type for which a single conversion function to integral or enumeration type exists (12.3). 条件应为整数类型,枚举类型或类型,其中存在单个转换函数为积分或枚举类型(12.3)。 If the condition is of class type, the condition is converted by calling that conversion function, and the result of the conversion is used in place of the original condition for the remainder of this section. 如果条件是类类型,则通过调用该转换函数来转换条件,并使用转换结果代替本节其余部分的原始条件。 Integral promotions are performed. 执行整体促销。 Any statement within the switch statement can be labeled with one or more case labels as follows: switch语句中的任何语句都可以用一个或多个case标签标记,如下所示:

case constant-expression : case constant-expression:

where the constant-expression shall be an integral constant-expression. 其中constant-expression应为整数常量表达式。 The integral constant-expression (5.19) is implicitly converted to the promoted type of the switch condition. 积分常量表达式(5.19)被隐式转换为切换条件的提升类型。 No two of the case constants in the same switch shall have the same value after conversion to the promoted type of the switch condition. 在转换为提升类型的开关条件后,同一开关中的两个外壳常数不应具有相同的值。

Your expression isn't a constant expression, even though the variable itself is const , so you can't switch on it. 您的表达式不是常量表达式,即使变量本身是const ,因此您无法打开它。 You'll need to use an if . 你需要使用if

You have another problem though: 你有另一个问题:

You create a union , 你创建一个union

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

...then you initialize the sz member of that union, ...然后你初始化该联盟的sz成员,

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

...and then you access the u member of that union. ...然后你访问该联盟的u成员。

static const unsigned int uMask1 = Mask1.u;  

This evokes undefined behavior according to the standard. 根据标准,这会引起不确定的行为。 In the language of the Standard, 2 members of a union can't be active at one time. 在标准的语言中,工会的2名成员不能同时处于活动状态。 Meaning you can't treat a union like a caster. 意思是你不能像施法者那样对待一个联盟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM