在C++中修改constexpr函数中的全局变量17

Dre*_*rew 36 c++ language-lawyer constexpr c++17

在C++ 17中,您是否可以修改constexpr函数中的全局变量?

#include <iostream>

int global = 0;

constexpr int Foo(bool arg) {
    if (arg) {
        return 1;
    }
    return global++;
}

int main() {
    std::cout << global;
    Foo(true);
    std::cout << global;
    Foo(false);
    std::cout << global;
}
Run Code Online (Sandbox Code Playgroud)

我不希望你能够,但clang 6允许它:https://godbolt.org/g/UB8iK2

但是,海湾合作委员会不会:https://godbolt.org/g/ykAJMA

哪个编译器正确?

Jos*_* D. 20

哪个编译器正确?

Clang是对的.

根据dcl.constexpr/3定义constexpr函数

constexpr功能的定义应满足下列要求:

(3.1)其返回类型应为字面类型;
(3.2)每个参数类型应为文字类型;
(3.3)其函数体应为= delete,= default或者包含的复合语句:

(3.3.1)asm-definition,
(3.3.2)goto语句,
(3.3.3)标识符标签,
(3.3.1)3.3.4)try-block,或
(3.3.5)非文字类型或静态或线程存储持续时间的变量的定义,或者不执行初始化的定义.

另外根据dcl.constexpr/5:

对于constexpr既不是默认也不是模板的函数或constexpr构造函数,如果不存在参数值,则函数或构造函数的调用可以是核心常量表达式的计算子表达式,

Foo(true)可以评估为核心常数表达式(即1).

此外,Foo(false) 可能但不需要进行持续评估.

结论

因此,GCC中的一个错误.


非常感谢@Barry,@ aschepler和@BenVoigt帮我解决这个问题.