It's impossible. constexpr
does not guarantee value inlining, you can see this manipulating optimization level here: https://godbolt.org/z/dAoiM-
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.
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.)
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.
It's worthwhile optimization-wise to write constexpr
functions and data structure, making sure the compiler can optimize, though you cannot force it to.
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;
}