`constexpr` 函数可以包含副作用吗?

问题描述 投票:0回答:0

我正在学习 '编程:使用 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
    函数产生副作用?

此外,当引用的最后一部分说“用于初始化”时,它指的是哪种情况?

c++ constexpr constexpr-function
© www.soinside.com 2019 - 2024. All rights reserved.