Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why static const members cannot appear in a constant expression like 'switch'

I have the following declaration of some static const members

.h

class MyClass : public MyBase
{
public:
    static const unsigned char sInvalid;
    static const unsigned char sOutside;
    static const unsigned char sInside;
    //(41 more ...)
}

.cpp

const unsigned char MyClass::sInvalid = 0;
const unsigned char MyClass::sOutside = 1;
const unsigned char MyClass::sInside = 2;
//and so on

At some point I want to use those value in a switch like :

unsigned char value;
...
switch(value) {
    case MyClass::sInvalid : /*Do some ;*/ break;
    case MyClass::sOutside : /*Do some ;*/ break;
    ...
}

But I get the following compiler error: error: 'MyClass::sInvalid' cannot appear in a constant-expression.

I have read other switch-cannot-appear-constant-stuff and didn't find an answer for me since I don't get why those static const unsigned char are not constant-expression.

I am using gcc 4.5.

like image 891
Thomas Vincent Avatar asked May 16 '12 13:05

Thomas Vincent


People also ask

Which type Cannot appear as a switch expression type?

1) The expression used in switch must be integral type ( int, char and enum). Any other type of expression is not allowed.

Can static members be const?

Constant static membersIf a static data member is declared constexpr, it is implicitly inline and does not need to be redeclared at namespace scope.

What is the difference between const and static const?

An instance const value can be computed in the ctor-initializer-list. A static const is set during startup initialization and remains unchanged for the rest of the program.

Is it static const or const static?

They mean exactly the same thing. You're free to choose whichever you think is easier to read. In C, you should place static at the start, but it's not yet required.


2 Answers

The problems you see are due to the fact that this

static const unsigned char sInvalid;

cannot be a compile time constant expression, since the compiler doesn't know its value. Initialize them in the header like this:

class MyClass : public MyBase
{
public:
    static const unsigned char sInvalid = 0;
    ...

and it will work.

like image 86
jpalecek Avatar answered Sep 21 '22 23:09

jpalecek


The values are indeed const, but they're not compile-time constants.

A switch condition is resolved at compile-time, not run-time. You can initialize sInvalid to whatever value, as long as it's only once, and the switch would never know about it until run-time.

It seems like you're better of using enums instead of static constants. Besides the fact that it would work, it seems more appropriate design-wise.

like image 36
Luchian Grigore Avatar answered Sep 23 '22 23:09

Luchian Grigore