Clang在编译时不为非constexpr变量求值constexpr函数的值

Dar*_*ell 5 c++ clang constexpr

一些代码:

constexpr int sum(int a, int b) {
    return a + b;
}

int main() {
    int a = sum(4, 5);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我使用编译此代码,clang-9int a在编译时不评估main函数的值。如果我使用constexpr int aclang在编译时对其进行评估,但我无法在运行时更改此变量。

但是在编译时gcc-7.1评估的值int a

为什么会这样呢?如何解决?

lub*_*bgr 5

如果希望在编译时预先计算一个值,然后将其绑定到允许修改的标识符,则只能通过constexprconstexpr对象初始化非对象来强制执行此操作:

constexpr int init = sum(4, 5);
int a = init;
Run Code Online (Sandbox Code Playgroud)


P.W*_*P.W 5

constexpr说明符仅表示可以在编译时评估函数的值。这并不意味着应该在编译时对其进行评估。因此,不同的编译器/版本在此问题上具有灵活性。

如果要在编译时强制执行此类求值,则分配给它的变量也应该为constexpr

发生这种情况时,aconstexpr int不只是一个普通的int

要解决您的特定问题,应使用中间变量,constexpr然后将其值分配给可以更改的变量。

  • @DarkHell让我们看看[clang实际产生了什么](https://godbolt.org/z/lmvYff)。您可以看到在带有`-g`的调试模式下,`sum`实际上在编译时没有评估。这使调试器可以进入“ sum”,因此您有合理的机会进行调试。当使用-O2启用优化时,它将在编译时评估所有内容。因此,clang让您在可调试性和性能之间进行选择。如果两者都需要,请考虑使用-Og进行优化,该优化不会抑制可调试性。 (6认同)