Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

static const double cannot have an in-class initializer. why is it so?

Tags:

c++

The problem with the following code is static member of type "const double" cannot have an in-class initializer. Why is applicable only for a 'const double'in the following code? Please help me.

class sample{
   static const char mc = '?';
   static const double md = 2.2;
   static const bool mb = true;
};
const char sample::mc;
const double sample::md;
const bool sample::mb;
int main(){
}
like image 429
sree Avatar asked Dec 04 '12 06:12

sree


3 Answers

The logic implemented by the C++03 language standard is based on the following rationale.

In C++ an initializer is a part of object definition. What you write inside the class for static members is actually only a declaration. So, formally speaking, specifying initializers for any static members directly inside the class is "incorrect". It is contrary to the general declaration/definition concepts of the language. Whatever static data you declare inside the class has to be defined later anyway. That's where you will have your chance to specify the initializers.

An exception from this rule was made for static integer constants, because such constants in C++ can form Integral Constant Expressions (ICEs). ICEs play an important role in the language, and in order for them to work as intended the values of integral constants have to be visible in all translation units. In order to make the value of some constant visible in all translation units, it has to be visible at the point of declaration. To achieve that the language allows specifying the initializer directly in class.

Additionally, on many hardware platforms constant integer operands can be embedded directly into the machine commands. Or the constant can be completely eliminated or replaced (like, for example, multiplication by 8 can be implemented as a shift by 3). In order to facilitate generation of machine code with embedded operands and/or various arithmetical optimizations it is important to have the values of integral constants visible in all translation units.

Non-integral types do not have any functionality similar to ICE. Also, hardware platforms do not normally allow embedding non-integral operands directly into the machine commands. For this reason the above "exception from the rules" does not extend to non-integral types. It would simply achieve nothing.

like image 85
AnT Avatar answered Oct 16 '22 16:10

AnT


The compiler offered me to use constexpr instead of const:

static_consts.cpp:3:29: error: ‘constexpr’ needed for in-class initialization of static data member ‘const double sample::md’ of non-integral type [-fpermissive]
static_consts.cpp:7:22: error: ‘constexpr’ needed for in-class initialization of static data member ‘const double sample::md’ of non-integral type [-fpermissive]

I've just accepted the offer:

class sample{
   static const char mc = '?';
   static constexpr double md = 2.2;
   static const bool mb = true;
};
const char sample::mc;
const bool sample::mb;
int main(){
}

And now it compiles just fine (C++11).

like image 24
anton_rh Avatar answered Oct 16 '22 16:10

anton_rh


Pre-C++11, only const integral types could be directly initialized in the class definition. It's just a restriction imposed by the standard.

With C++11, this no longer applies.

like image 13
Luchian Grigore Avatar answered Oct 16 '22 16:10

Luchian Grigore