It is known that:
double
is not an integral type and should be marked as a constexpr
.
Executables produced in a machine can run in other machines where floating point representation computation is different. Integral Constant Expressions do not change.
Marking an object static
says that it can be known by all observers, and making it const
is saying that the value does not change. The compiler can generate a value (e.g. 314 ) and put it in the read-only section, because the range is defined in the standard.
On the other hand double
is not in the standard and cannot have its ranged check and the value stored at compile-time, in class definitions. One could easily end up with having different object files with objects having a different value for that static const double
, thus breaking ODR.
Here is a simple example:
struct foo
{
static char const a = 1/11; // everyone gets 0 at compile-time
};
You would say then , but this can happen for doubles and at first look, something like this
struct foo
{
static double const y=1.0/11.0; // the true value is 0.090909...
};
seems verifiable, but the representation in double in one machine will be 0.09091
in another 0.090909091
.
Using constexpr
permits to say to the compiler that the input necessary to verify this is available at compile-time . However, actual evaluation can happen at run-time.
Since object files produced by C++ compilers can move to machines with different floating point representations , you have to tell that this checking must be made during compile time to ensure that consistency.
The question is a typical example of an XY-problem. Instead of asking , "why do I have to mark anything with constexpr
?" a puzzle char
-vs-float
is given. Now the question is, "why do we have to use constexpr
for non-integral types?", and here you can find your answer .