假设我有一个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
)文件中声明的,该怎么办? -那会改变一切吗?
答案 0 :(得分:15)
const int
仅在从constant expression初始化时才可以用作https://www.npmjs.com/package/ftp的一部分,但不能保证它是{3}}的一部分。
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?。