Switch error :: cannot be displayed in constant expression

This is strange...

I play with some decompression algorithm. Instead of going through char buffer[] and the loop until a stop bit is found in buffer[i] , I'm trying to use some bit mask methods, but with characters.

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 union material (actual code compilations work fine for this) and without considering whether the return function is good for Foo , I get '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 apply to uMask2 and Mask2.u

What am I missing?

Thanks in advance

+6
c ++ switch-statement compiler-errors
source share
2 answers

The confusion comes from the fact that const and const are two.

In the case of the switch statement, "constant expressions" are needed. In other words: expressions that can be "computed" by the compiler at compile time. This can be a hard-coded number (for example, 42) or something that was previously defined as a number (using #define).

Const is also used by the compiler with the value "when this variable matters, it will no longer change." For example. in the following code:

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

will be const. I cannot change the value of const, but that does not make it a “constant expression” for the compiler.

In your case, uMask1 is const (can no longer modify it), but is not a constant expression.

+6
source share

case condition expression must be an integer type or converted to an integer type and must be const.

6.4.2 [stmt.switch]

The condition must be an integer type, an enumeration type, or a class type, for which one conversion is performed; a function to an integral or enumeration type exists (12.3). If the condition has a class type, the condition is converted by calling this function conversion and the conversion result is used instead of the original condition for the remainder of this section. Integral promotions are being implemented. Any expression inside a switch statement can be marked with one or more shortcuts as follows:

random expression:

where the constant expression must be an integral constant expression. the integral constant expression (5.19) is implicitly converted to a type of switching condition. No two case constants in the same switch should have the same value after converting to an advanced type state switch.

Your expression is not a constant expression, although the variable itself is const , so you cannot include it. You need to use if .

You have one more problem:

You create a union ,

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

... then you initialize the sz member of this union,

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

... and then you get access to member u this union.

 static const unsigned int uMask1 = Mask1.u; 

This causes undefined behavior according to the standard. In the language of the Standard, 2 union members cannot be active at the same time. This means that you cannot heal the union as a caster.

+1
source share

All Articles