杀死幻数:"const int" vs "constexpr int"(或者最后没有区别)



假设我有一个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)文件,该怎么办 - 这会改变事情吗(如果是这样,如何)?

const int只有在常量表达式初始化时才能用作常量表达式的一部分,但它不能保证它是常量表达式的一部分。

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是更好的选择。

在这种情况下,

两者之间是否有任何有意义的区别(我记得编译推断 - 在任何一种情况下 - 值都不会改变,并且实际上硬编码了生成的循环/展开循环/任何代码中的 42)还是归结为个人品味?

在您展示的情况下,代码生成不会有任何区别。

但是,不同之处在于constexpr变量保证该值在编译时是已知的。参见维托里奥·罗密欧的回答。

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

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

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

在一个相关的问题中:如果幻数(以及替换它的东西)是在头文件中而不是 .ccp 文件中声明的,这会改变事情吗?

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

有关详细信息,请参阅标头中的"const"和"constexpr"变量是否应该"内联"以防止违反 ODR?

相关内容

  • 没有找到相关文章

最新更新