如何判断在编译时是否评估了constexpr(无需手动检查) [英] How to tell if `constexpr` is evaluated at compile time (without manual inspection)

查看:78
本文介绍了如何判断在编译时是否评估了constexpr(无需手动检查)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种标准的方法来找出编译器对 constexpr 函数的作用?

Is there a standard way to find out what the compiler does to constexpr functions?

(注意:对于调试,默认情况下,每个constexpr函数都默认延迟到运行时。为什么这样明智?有没有办法影响这一点?)

(Side note: For debug, every constexpr function is deferred to runtime by default. Why is this sensible? Is there a way to influence this?)

对于发布,它取决于上下文。显然,对于较小的测试设置,您可以轻松地检查生成的机器代码,但这并不是真正项目的方法。

For release it depends on the context. Obviously, for small test settings you can easily inspect the generated machine code, but this cannot be the way to go for a real project.

我当前的解决方法(VC ++ )是要破坏某个地方,请转到我的constexpr函数并(尝试)检查反汇编。如果没有,我得出的结论是所有这些都是在编译时完成的。
但这不是100%可靠的方法。 (优化等)
只能确定另一种方法:如果我确实发现了反汇编(甚至可以在那里分解),我知道它不是在编译时完成的。

My current 'workaround' (VC++) is to break somewhere, go to my constexpr function and (try to) inspect the disassembly. If none is there, I conclude that it was all done at compile time. But it is not 100% reliable this way. (Optimization, etc.) Only the other way around is certain: If I do find disassembly (and can even break there), I know that it was NOT done at compile time.

推荐答案

这是不可能的。 constexpr 可以不保证值内联,您可以在此处查看此优化级别: https://godbolt.org/z/dAoiM -

It's impossible. constexpr does not guarantee value inlining, you can see this manipulating optimization level here: https://godbolt.org/z/dAoiM-

仅由于-O2,所有内容都被内联并且结构被分解。在此之下,即使对于 constexpr 上下文中使用的代码,编译器也会愉快地使用运行时评估。

Only since -O2 everything is inlined and the structure gets dissolved. Below that compiler happily uses runtime evaluation even for code used in constexpr context.

没有标准语言工具来询问编译器是否应用了特定的优化。归结为视情况而定。如果代码行为相同,则编译器可以对其执行任何操作。唯一的例外是强制性RVO和其他RVO(允许它们更改观察到的行为。)

There are no standard language tools to inquire whether compiler applies particular optimization. It all boils down to the as-if rule. If the code behaves the same compiler can do anything to it. The only exception is mandatory RVO and other RVOs (they are allowed to changed observed behaviour.)

话虽如此。 constexpr 是一个有用的提示。在链接的示例中,如果删除了 constexpr 的说明符,即使 O3 (在最近的clang和gcc上)也无法删除

That being said. The constexpr is a useful hint. In the linked example if one removes constexpr specifiers even O3 (on recent clang and gcc) does not manage to remove the map.

constexpr 函数和数据结构是值得优化的,确保编译器可以优化,虽然您不能强迫它。

It's worthwhile optimization-wise to write constexpr functions and data structure, making sure the compiler can optimize, though you cannot force it to.

您可以强制在 constexpr 上下文中对函数进行求值,还可以防止抛出非constexpr路径,以防止保证运行时评估。

You can force function to be evaluated in constexpr context, and you can also guard non-constexpr paths to throw, to prevent guaranteed run-time evaluation.

#include <iostream>
#include <vector>
using namespace std;

constexpr int f(int el) {
    return el > 0 ? el : throw "error";
}

int main() {
    // constexpr auto r = f(-1); // #1 compiler errors that throw is forbidden in  
                                 // constexpr, so it went into a non-constexpr path
                                 // and failed

    constexpr auto r = f(1);     // #2 fine - has to be interpreted in constexpr context
    cout << f(1) << '\n';        // #3 fine - can be interpreted in both contexts

    try {
        cout << f(-1) << '\n'; // # 4 // throws - i.e. runtime evaluation
    }
    catch (const char* e) {
        cout << e << '\n';
    }
    return 0;
}

这篇关于如何判断在编译时是否评估了constexpr(无需手动检查)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆