【发布时间】:2017-04-28 18:47:08
【问题描述】:
对于定义如下整数类型的编译时常量(在函数和类范围内),哪种语法最好?
static const int kMagic = 64; // (1)
constexpr int kMagic = 64; // (2)
(1) 也适用于 C++98/03 编译器,而 (2) 至少需要 C++11。两者之间还有其他区别吗?在现代 C++ 代码中应该首选其中一个吗?为什么?
编辑
我用Godbolt's CE尝试了这个示例代码:
int main()
{
#define USE_STATIC_CONST
#ifdef USE_STATIC_CONST
static const int kOk = 0;
static const int kError = 1;
#else
constexpr int kOk = 0;
constexpr int kError = 1;
#endif
return kOk;
}
对于 static const 情况,这是 GCC 6.2 生成的程序集:
main::kOk:
.zero 4
main::kError:
.long 1
main:
push rbp
mov rbp, rsp
mov eax, 0
pop rbp
ret
另一方面,constexpr 是:
main:
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], 0
mov DWORD PTR [rbp-8], 1
mov eax, 0
pop rbp
ret
虽然在-O3 在这两种情况下我都得到了相同的(优化的)程序集:
main:
xor eax, eax
ret
编辑#2
我试过这个简单的代码(live on Ideone):
#include <iostream>
using namespace std;
int main() {
const int k1 = 10;
constexpr int k2 = 2*k1;
cout << k2 << '\n';
return 0;
}
这表明const int k1 在编译时 被评估,因为它用于计算constexpr int k2。
不过,doubles 的行为似乎不同。我为 here 创建了一个单独的问题。
【问题讨论】:
-
我更喜欢
constexpr方法。它是显式和strong。无论如何,从链接的角度来看,另一种选择也不相同:如果您输入const(或static,或两者兼而有之),它会使变量具有内部链接。所以它们在语义上是不同的。 -
更喜欢哪一个取决于您将它们用于什么。正如@Nawaz 所说,这两个示例做了不同的事情,如果不提及它们的预期用途,就不可能决定哪个“更好”。
-
在什么范围内定义它们?
-
@Mr.C64 当你创建一些类,它会被用作模板的参数时,这是使用 constexpr 的好时机:所有成员都是 constexpr,而
static const不能做这个。 ---- 这就是我想说的。 -
您编辑中的 GCC 程序集证明不了任何事情。
标签: c++ c++11 constants constexpr