我正在学习 '编程:使用 C 的原理和实践',需要一些帮助来理解
constexpr
功能上的这一点,在 page 291:
constexpr 函数的行为就像一个普通函数,直到你在需要常量的地方使用它。 然后,如果它的参数是常量表达式(例如 p2),它会在编译时计算,如果它们不是(例如,p1)。要实现这一点,constexpr 函数必须非常简单,以便编译器(每个符合标准的编译器)可以对其进行评估。在 C++11 中,这意味着 constexpr 函数必须有一个由单个返回语句(如 scale())组成的函数体;在 C++14 中,我们还可以编写简单的循环。 constexpr 函数可能没有副作用;也就是说,它可能不会更改其自身外部变量的值,除了那些分配给它或用于初始化的变量。
为简单起见,这是一个违反这些规则的函数示例:
#include <iostream> int glob = 9; constexpr void bad(int & arg) { // error: no return value ++arg; // error: modifies caller through argument glob = 7; // error: modifies nonlocal variable }
但是,此代码使用 gcc 11.2.0 编译:
#include <iostream>
int glob = 9;
int b = 1;
constexpr void bad(int & arg) {
++arg;
glob = 7;
}
int main() {
std::cout << glob << b;
bad(b);
std::cout << glob << b;
}
但我不确定它为什么会编译。
bad
在非常量上下文中被调用,因此表现得像一个普通函数(根据引用的第一句)?constexpr
函数产生副作用?此外,当引用的最后一部分说“用于初始化”时,它指的是哪种情况?