constexpr与静态const:更喜欢哪一个? [英] constexpr vs. static const: Which one to prefer?

查看:146
本文介绍了constexpr与静态const:更喜欢哪一个?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于定义如下整数类型(在函数和类范围)的编译时常量,哪种语法最好?

static const int kMagic = 64; // (1)
constexpr int kMagic = 64;    // (2)

(1)对于C ++ 98/03编译器也适用,相反,(2)至少需要C ++ 11。两者之间还有其他区别吗?

(1) works also for C++98/03 compilers, instead (2) requires at least C++11. Are there any other differences between the two? Should one or the other be preferred in modern C++ code, and why?

编辑

我使用 Godbolt的CE 尝试了以下示例代码:

I tried this sample code with 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;
}

静态常量这是GCC 6.2生成的程序集:

and for the static const case this is the generated assembly by 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 中,我都得到了相同的(优化的)程序集: / p>

Although at -O3 in both cases I get the same (optimized) assembly:

main:
        xor     eax, eax
        ret






编辑#2

我尝试了这个简单代码 (在Ideone上直播)

I tried this simple code (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

which shows that const int k1 is evaluated at compile-time, as it's used to calculate constexpr int k2.

但是, double s似乎有不同的行为。我为此在此处创建了一个单独的问题

However, there seems to be a different behavior for doubles. I've created a separate question for that here.

推荐答案

只要我们在谈论声明 scalar 整数的编译时常量,或枚举类型,使用 const (在类范围内为 static const )或 constexpr 。

As long as we are talking about declaring compile-time constants of scalar integer or enum types, there's absolutely no difference between using const (static const in class scope) or constexpr.

请注意,要求编译器在常量表达式中支持 static const int 对象(用常量初始化程序声明)。他们别无选择,只能将此类对象视为编译时常量。此外,只要此类对象保持odr未被使用,就不需要定义,这进一步证明了它们不会用作运行时值。

Note that compilers are required to support static const int objects (declared with constant initializers) in constant expressions, meaning that they have no choice but to treat such objects as compile-time constants. Additionally, as long as such objects remain odr-unused, they require no definition, which further demonstrates that they won't be used as run-time values.

常量初始化规则可以防止本地静态const int 对象被动态初始化,这意味着在本地声明此类对象不会造成性能损失。此外,整数 static 对象对静态初始化的排序问题的免疫力是该语言的一个非常重要的功能。

Also, rules of constant initialization prevent local static const int objects from being initialized dynamically, meaning that there's no performance penalty for declaring such objects locally. Moreover, immunity of integral static objects to ordering problems of static initialization is a very important feature of the language.

constexpr 是该概念的扩展和泛化,最初是通过 const 使用常量初始化程序在C ++中实现的。对于整数类型 constexpr 不能提供 const 已经提供的功能。 constexpr 只是对初始化程序的常数进行早期检查。但是,也许有人会说 constexpr 是专门为此目的设计的功能,因此在样式上更适合。

constexpr is an extension and generalization of the concept that was originally implemented in C++ through const with a constant initializer. For integer types constexpr does not offer anything extra over what const already did. constexpr simply performs an early check of the "constness" of initializer. However, one might say that constexpr is a feature designed specifically for that purpose so it fits better stylistically.

这篇关于constexpr与静态const:更喜欢哪一个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆