Is there a standard way to find out what the compiler does to constexpr
functions?
(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.
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.
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 removesconstexpr
specifiers evenO3
(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.As we now have the current C++20 standard, we can use
consteval
.From the docs:
This will fix the problem with
constexpr
.