PaolaJ.
PaolaJ.

Reputation: 11562

static const int in switch statement from another class cause error C2051: case expression not constant

I have one simple class like

class Person {
  static const int MALE; // in Person.cpp initialized = 1
  static const int FEMALE;//in Person.cpp initialized = 2
};

In Company class (Company.cpp file, I have company class) I have function with switch

 switch(x){// x is int passed as parameter to function
        case Person::MALE:
            //do something
        break;
        case Person::FEMALE:
            //do something
        break;
}

but when I try to build I got error error C2051: case expression not constant for lines in case in switch above What is a problem when it is a const ?

Upvotes: 3

Views: 3381

Answers (5)

Ben Voigt
Ben Voigt

Reputation: 283793

A const is not a constant expression unless

  • It is a const variable of integral type, previously initialized with a literal or other constant expression.

C++11 adds constexpr, which can be used with variables of non-integral type, but the requirement for a prior initialization still applies.

Your problem is that in Company.cpp, this variable has not been initialized. The compiler will have to assume that the actual definition involves a runtime calculation. For example, it is perfectly legal to write const int Person::MALE = rand();

Or if Person.cpp contained

const int Person::MALE = 1;
const int Person::FEMALE = 1;

then the compiler would have to reject Company.cpp because the cases are not unique. How would that work? What if someone edited Person.cpp after Company.cpp was already compiled?

Upvotes: 3

James Kanze
James Kanze

Reputation: 154007

According to the C++11 standard: an expression is not a constant expression if it contains an lvalue-to-rvalue conversion, unless it is applied to "a glvalue of integral or enumeration type that refers to a non-volatile const object with a preceding initialization, initialized with a constant expression". (There are some other cases, but they don't apply here.) Note the requirement for a "preceding initialization"; not only must the variable be const, but the compiler must be able to see its initialization.

Earlier versions of the standard were somewhat vague in this regard, and the natural interpretation of what they literally say would suggest that your code be legal. This was certainly not what was intended, however; no compiler implemented it in this way (since it would generally require breaking separate compilation), and C++11 clearly says that this is illegal.

Upvotes: 1

youdontneedtothankme
youdontneedtothankme

Reputation: 672

C++ is not java. Use enums:

enum Person
{
  Person_male = 1,
  Person_female = 2
};

Upvotes: 0

Ivan Smirnov
Ivan Smirnov

Reputation: 4435

Values used in case expressions should be already known on compile-time, because they are somewhat "hardcoded" into binary code. And here they are specified only at a linkage phase. Probably the solution might be following:

// person.h
enum Person { MALE, FEMALE };

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 311088

Change the declarations of static data members the following way

class Person {
  static const int MALE = 1;
  static const int FEMALE = 2;
};

The compiler must know the values of case labels during the compilation time.

Upvotes: 10

Related Questions