有没有一种标准方法可以找出编译器做了什么constexpr
功能?
(旁注:对于调试,默认情况下每个 constexpr 函数都会推迟到运行时。为什么这是明智的?有没有办法影响这一点?)
对于发布取决于上下文。显然,对于小型测试设置,您可以轻松检查生成的机器代码,但这不是实际项目的方法。
我当前的“解决方法”(VC++)是在某个地方中断,转到我的 constexpr 函数并(尝试)检查反汇编。如果没有,我的结论是这一切都是在编译时完成的。
但这种方式并不是100%可靠。 (优化等)
只有相反的方式是确定的:如果我确实找到反汇编(甚至可以在那里中断),我知道它不是在编译时完成的。
不可能。 constexpr
不保证值内联,您可以在此处查看此操作优化级别:https://godbolt.org/z/dAoiM-
仅从 -O2 开始,所有内容都被内联并且结构被溶解。下面,编译器愉快地使用运行时评估,即使对于使用的代码constexpr
语境。
没有标准语言工具可以查询编译器是否应用特定的优化。这一切都归结为假设规则。如果代码的行为相同,编译器可以对其执行任何操作。唯一的例外是强制性 RVO 和其他 RVO(允许它们改变观察到的行为。)
话虽如此。这constexpr
是一个有用的提示。在链接的示例中,如果删除constexpr
说明符甚至O3
(在最近的 clang 和 gcc 上)无法删除地图。
从优化角度来说,编写是值得的constexpr
函数和数据结构,确保编译器可以优化,尽管你不能强迫它这样做。
您可以强制对函数进行评估constexpr
上下文,您还可以保护要抛出的非 constexpr 路径,以防止有保证的运行时评估。
#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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)