Constant class members in case statements
Hi,
I have a constant integer variable (i) as a class member of my Class X.
This variable (i) is initialized in the constructor of Class X.
However, why does the compiler prevent the use of the variable (i) in a case statement in the switch-case construct ? After all, is 'i' not a constant ?
The compiler error shown is
Error C2051 : case expression is not constant
Code:
X::X():i(10)
{
}
void X::MyFunction()
{
switch(_someValue)
{
case i :
{
}
};
}
This works if I had defined 'i' as a 'static const int' and initialized it at the point of class declaration.
Could you please explain the above difference ?
Re: Constant class members in case statements
>> case expression is not constant
And it needs to be. This means that the compiler must know the value of "i" at compile time. If "i" isn't constant, then the compiler can't know the value. Use an if statement and "i" can't be constant.
Also, variables with a leading underscore are reserved for "the system".
gg
Re: Constant class members in case statements
case label value is required to be not a constant (like, constant variable), but integral constant-expression, and these are, among others, literal values, or constant valiables initialized with literal values. const data member is not integral constant expression, because it might be initialized with non-literal value (i.e. via initialization list in constructor), so it cannot be used in case label.
Cheers
Re: Constant class members in case statements
Thanks for your answers !
Quote:
Originally Posted by
Hobson
case label value is required to be not a constant (like, constant variable), but integral constant-expression, and these are, among others, literal values, or constant valiables initialized with literal values
Could you please explain with an example what you meant by "const variables initialized with literal values" ?
Re: Constant class members in case statements
Quote:
Originally Posted by
Codeplug
>> case expression is not constant
And it needs to be. This means that the compiler must know the value of "i" at compile time. If "i" isn't constant, then the compiler can't know the value. Use an if statement and "i" can't be constant.
gg
'i' is indeed constant because I have declared the variable as [const int i ] in the private section of the class declaration.
How is it that a member declaration of [static const int i = 10] works without a problem but not [const int i]
Re: Constant class members in case statements
Sure, here it is:
Code:
#include <string>
#include <vector>
#include <iostream>
using std::cin;
using std::cout;
int function() {return 5;}
int main() {
//constant variable initialized with literal value
const int label_literal_val = 10;
//constant variable initialized with expression value
const int label_function_val = function();
int number;
cin >> number;
switch(number) {
//no error, case label value is a constant expression
//(constant variable initialized with literal value)
case label_literal_val:
cout << "'literal' case\n";
break;
//error, case label value is not a constant expression
//constant variable initialized other way than literal
case label_function_val:
cout << "'function' case\n";
break;
default:
cout << "Default case\n";
break;
}
}
Re: Constant class members in case statements
Quote:
Originally Posted by
humble_learner
'i' is indeed constant because I have declared the variable as [const int i ] in the private section of the class declaration.
How is it that a member declaration of [static const int i = 10] works without a problem but not [const int i]
A member variable may differ between instances. Therefore it is not really a constant.
Remember a switch statement must be convertable into an array of "gotos" (jumps). This array is build by the compiler ONCE at compile time. So if you have:
Code:
swtich (X)
{
case 0: break;
case 2: break;
case 3: break;
default: break;
}
The compiler will generate a 4 element array with
Code:
[0] = "goto case 0:";
[1] = "goto default:";
[2] = "goto case 2:";
[3] = "goto case 3:";
This table is immutable (it can not be changed ar runtime).
Now it should be obvious why each case value must be a hard compile time contant integral expression.