问题描述
以下代码无法编译:
#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;
替换 const $ c带有
的$ c>声明rel = noreferrer>编译成功。 constexpr
,kPi
Substituting the const
declaration for kPi
with constexpr
, it compiles successfully.
另一方面,当 int
为使用而不是 double
,似乎是 const
与 constexpr
:
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;
}
为什么 int
和 double
对于使用 const
初始化 constexpr
会得到不同的处理方式
这是Ideone编译器中的错误吗? C ++标准要求吗?为什么?
上面的代码是UB吗?
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?
PS 我尝试使用Visual Studio 2015 C ++编译器,并且它会编译第一个代码片段(用 const
初始化 constexpr
)。
P.S. I tried with Visual Studio 2015 C++ compiler, and it compiles the first code snippet (initializing constexpr
with const
) just fine.
推荐答案
对于要在编译时计算的constexpr,在该constexpr的初始化中使用的所有内容也必须在编译时计算。
如果将某些内容声明为const,则并不意味着该值将在编译时可用。
The for a constexpr to be calculated at compile time everything that is used in the initialization of that constexpr also must be calculatable at compile time.If you declare something as const it does not mean that the value will be available at compile time.
执行以下行:
const double dbl = 2.;
未指定 double
的表示形式按照标准,因此操作系统将不得不处理此问题。因此,当操作系统加载您的程序时,二进制文件中会包含一个特殊的汇编子例程,该子例程将使这种情况发生。
如果使用 int
,则表示是由标准指定的,因此编译器将知道如何使用它。但是,也可以通过将 double
设置为 constexpr
来实现相同的功能,因此编译器将在编译时对其进行计算。在这种情况下, double
还将是 const
(您不能创建 constexpr
而不使它成为 const
)。
The double
's representation is not specified by the standard so the OS will have to deal with this. So when your program is loaded by the OS there is a special assembly subroutine in your binary that will make this happen.If you use an int
the representation is specified by the standard so the compiler will know how to work with it. However the same can be achieved by making the double
a constexpr
as well, so the compiler will compute it in compile time. In this case the double
will also be a const
(you cannot make something constexpr
without also making it const
).
因此这将起作用:
constexpr double kPi = 3.14;
constexpr double kPi2 = 2.0*kPi;
如果使用整数,则编译器将在编译时设置该const的值,因此constexpr将
If you use an int the compiler will set the value of that const at compile time so the constexpr will work.
请记住,不同的编译器可以将 const
解释为 constexpr
在某些情况下并使其起作用。但这不是标准的一部分。
Keep in mind that different compilers can interpret const
as constexpr
in some cases and make it work. But that is not part of the standard.
这篇关于用const初始化constexpr:对int和double的不同处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!