Killing Magic Numbers:"const int" vs "constexpr int"(或者最后没有区别)
Killing Magic Numbers: "const int" vs "constexpr int" (or is there no difference in the end)
假设我有一个 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
实际上是硬编码在结果 loop/unrolled loop/whatever machine-code) 还是取决于个人品味?
在相关问题中:如果 magic number
(以及替换它的东西)是在 header(.h
)文件而不是源文件(.ccp
) 文件 - 这会改变事情吗(如果是,如何改变)?
const int
可以用作 constant expression 的一部分,前提是它是从一个初始化的,但它不能保证它是。
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
是更好的选择。
Is there any meaningful difference between the two in this case (I recall the compilering deducing that - in either case - the value does not change and actually hardcodes the 42 in the resulting loop/unrolled loop/whatever code) or does it come down to personal taste?
在您展示的案例中,codegen 不会有任何差异。
但是,不同之处在于 constexpr
变量保证在 compile-time 处已知该值。参见 。
如果它确实是一个 compile-time 值,写 constexpr
也很好,用于文档目的:当有人阅读您的代码并看到 constexpr
时,他们会自动知道它是一个真正的固定值。这在初始化为 non-trivial 的情况下很重要(例如调用函数)。
您还可以将 constexpr
变量视为包含文字的 C 宏的真正替代品(例如 #define FOO 123
)。
最后,请记住 constexpr
意味着 const
。
In a related issue: what if the magic number (and the thing that replaces it) were declared in a header file instead of a .ccp file - would that change things?
没有。但是,如果您在头文件中声明全局变量,您可能希望在 constexpr
之上使用 inline
(在 C++17 中可用),这样您在头文件中只有一个实体程序,这有利于避免 ODR 问题并可能节省内存和初始化时间。
有关详细信息,请参阅 。
假设我有一个 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
实际上是硬编码在结果 loop/unrolled loop/whatever machine-code) 还是取决于个人品味?
在相关问题中:如果 magic number
(以及替换它的东西)是在 header(.h
)文件而不是源文件(.ccp
) 文件 - 这会改变事情吗(如果是,如何改变)?
const int
可以用作 constant expression 的一部分,前提是它是从一个初始化的,但它不能保证它是。
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
是更好的选择。
Is there any meaningful difference between the two in this case (I recall the compilering deducing that - in either case - the value does not change and actually hardcodes the 42 in the resulting loop/unrolled loop/whatever code) or does it come down to personal taste?
在您展示的案例中,codegen 不会有任何差异。
但是,不同之处在于 constexpr
变量保证在 compile-time 处已知该值。参见
如果它确实是一个 compile-time 值,写 constexpr
也很好,用于文档目的:当有人阅读您的代码并看到 constexpr
时,他们会自动知道它是一个真正的固定值。这在初始化为 non-trivial 的情况下很重要(例如调用函数)。
您还可以将 constexpr
变量视为包含文字的 C 宏的真正替代品(例如 #define FOO 123
)。
最后,请记住 constexpr
意味着 const
。
In a related issue: what if the magic number (and the thing that replaces it) were declared in a header file instead of a .ccp file - would that change things?
没有。但是,如果您在头文件中声明全局变量,您可能希望在 constexpr
之上使用 inline
(在 C++17 中可用),这样您在头文件中只有一个实体程序,这有利于避免 ODR 问题并可能节省内存和初始化时间。
有关详细信息,请参阅