杀死魔术数字:“ const int” vs“ constexpr int”(或最后没有区别)

时间:2019-07-09 10:05:30

标签: c++ const constexpr magic-numbers

假设我有一个magic number我想摆脱...

//whatever.cpp

for (int i = 0; i < 42; i++)
{
    //...
}

我可以通过两种方式杀死它:

使用const int SOMETHING_SOMETHING_MEANING_OF_LIFE = 42
或使用constexpr int SOMETHING_SOMETHING_MEANING_OF_LIFE = 42
在源.cpp文件中。

在这种情况下,两者之间是否有任何有意义的区别(我记得编译器推断出-在任何一种情况下-值均不变,因此42实际上被硬编码在结果循环/展开循环中) /无论使用哪种机器代码),还是取决于个人喜好?

一个相关的问题:如果magic number(以及替换它的东西)是在标头(.h)文件而不是源(.ccp)文件中声明的,该怎么办? -那会改变一切吗?

2 个答案:

答案 0 :(得分:15)

const int仅在从constant expression初始化时才可以用作https://www.npmjs.com/package/ftp的一部分,但不能保证它是{

const int i = 42; // OK, usable in a constant expression
int j = 42;
const int k = j;  // OK, not usable in a constant expression

constexpr int确保变量的初始化程序是常量表达式,否则程序将无法编译。

constexpr int i = 42; // OK, usable in a constant expression
int j = 42;
constexpr int k = j;  // Compile-time error, 'j' is not a constant expression

因此,如果要确保初始化程序确实是常量表达式,则constexpr是更好的选择。

答案 1 :(得分:11)

  

在这种情况下两者之间是否有任何有意义的区别(我记得编译器推断出-在任何一种情况下-值均未更改,实际上将42硬编码到结果循环/展开循环/任何代码中)还是执行了归结为个人品味?

在您显示的情况下,代码生成不会有任何差异。

但是,区别在于constexpr变量可确保在编译时知道该值。参见@VittorioRomeo的答案。

如果constexpr确实是一个编译时值,那么出于文档目的,也可以写它:当某人读取您的代码并看到constexpr时,他们会自动知道它是一个真正的固定值。在初始化很简单的情况下(例如,对函数的调用),这一点很重要。

您还可以看到constexpr变量真正替代了包含文字(例如#define FOO 123)的C宏。

最后,请记住,constexpr意味着const

  

一个相关的问题:如果幻数(及其替换物)在头文件而不是.ccp文件中声明,会发生什么变化?

不。但是,如果要在头文件中声明全局变量,则可能要在inline上使用constexpr(在C ++ 17中可用),以便在目录中只有一个实体。程序,这是避免ODR问题并可能节省内存和初始化时间的优势。

有关更多信息,请参见Should `const` and `constexpr` variables in headers be `inline` to prevent ODR violations?