使用const初始化constexpr:int和double的不同处理

时间:2016-12-14 11:42:25

标签: c++ c++11 const constexpr

以下代码无法编译live on Ideone

#include <iostream>
using namespace std;

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

错误消息是:

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;

constit compiles successfully代替kPi constexpr声明。

另一方面,当使用int代替double时,似乎const plays wellconstexpr

#include <iostream>
using namespace std;

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

为什么intdouble使用constexpr初始化const会有不同的处理方法?
这是Ideone编译器中的错误吗?这是C ++标准所要求的吗?那是为什么?
上面的代码是UB吗?

P.S。我尝试使用Visual Studio 2015 C ++编译器,它编译了第一个代码段(用constexpr初始化const)就好了。

3 个答案:

答案 0 :(得分:1)

对于要在编译时计算的constexpr,在该constexpr的初始化中使用的所有内容也必须在编译时计算。 如果将某些内容声明为const,则并不意味着该值将在编译时可用。

执行以下行:

const double dbl = 2.;

该标准未指定double的表示形式,因此OS必须对此进行处理。因此,当您的程序由OS加载时,二进制文件中会包含一个特殊的汇编子例程,该子例程将使这种情况发生。 如果使用int,则表示是由标准指定的,因此编译器将知道如何使用它。但是,也可以通过将double设为constexpr来实现相同的目的,因此编译器将在编译时对其进行计算。在这种情况下,double也将是const(您不能同时制作constexpr就不能制造const)。

这将起作用:

constexpr double kPi = 3.14;
constexpr double kPi2 = 2.0*kPi;

如果使用整数,则编译器将在编译时设置该const的值,以便constexpr可以工作。

请记住,在某些情况下,不同的编译器可以将const解释为constexpr并使其起作用。但这不是标准的一部分。

答案 1 :(得分:0)

Shafik Yaghmour已经提供link explaining the background

由于我必须维护必须使用不同标准编译的代码,因此我使用以下宏:

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

答案 2 :(得分:-3)

规则:“constexpr必须在编译时”进行评估。

让我们看下面的代码(通用示例);

    const double k1 = size_of_array(); 

k1是常量,其初始化程序的值不知道编译时间,但其初始化程序在运行时间之前是已知的,因此k1不是常量表达式。因此,const变量不是constexpr。

但编译器会看到这些代码:

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

发生一个例外。 constexpr积分值可用于需要const整数的任何位置,例如模板参数和数组声明 [1]

您可以从以下链接获取更多信息:

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