Initializing constexpr with const: Different treatment for int and double

放肆的年华 提交于 2020-01-01 04:11:07

问题


The following code fails to compile live on Ideone:

#include <iostream>
using namespace std;

int main() {
    const double kPi = 3.14;
    constexpr double kPi2 = 2.0*kPi;
    cout << kPi2;
}

The error message is:

prog.cpp: In function 'int main()':
prog.cpp:6:30: error: the value of 'kPi' is not usable in a constant expression
  constexpr double kPi2 = 2.0*kPi;
                              ^
prog.cpp:5:15: note: 'kPi' was not declared 'constexpr'
  const double kPi = 3.14;

Substituting the const declaration for kPi with constexpr, it compiles successfully.

On the other hand, when int is used instead of double, seems like const plays well with constexpr:

#include <iostream>
using namespace std;

int main() {
    const int k1 = 10;
    constexpr int k2 = 2*k1;
    cout << k2 << '\n';
    return 0;
}

Why do int and double get different treatments for initializing a constexpr with const?
Is this a bug in the Ideone compiler? Is this required by the C++ standard? Why is that?
Was the above code UB?

P.S. I tried with Visual Studio 2015 C++ compiler, and it compiles the first code snippet (initializing constexpr with const) just fine.


回答1:


Shafik Yaghmour already provided a link explaining the background.

Since I have to maintain code which has to compile with different standards, I use the following macro:

#if __cplusplus <= 199711L  // lower than C++11
  #define MY_CONST const
#else // C++11 and above
  #define MY_CONST constexpr
#endif



回答2:


Rule:"constexpr must be evaluate at compile time".

Let's look below code (generic example);

    const double k1 = size_of_array(); 

k1 is constant, the value of its initializer is not known compile time but its initializer is known until run time so k1 is not constant expression. As a result a const variable is not constexpr.

But compiler see these code:

    const int k1 = 10;  
    constexpr int k2 = 2*k1;

One exception occurs. A constexpr integral value can be used wherever a const integer is required, such as in template arguments and array declarations [1].

You can get extra information from the links below:

  1. Constexpr - Generalized Constant Expressions in C++11
  2. const vs constexpr on variables | stackoverflow
  3. Difference between constexpr and const | stackoverflow


来源:https://stackoverflow.com/questions/41141734/initializing-constexpr-with-const-different-treatment-for-int-and-double

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!