6 ms·
Except constexpr isn't a guarantee. Compilers can choose to silently evaluate constexpr things at runtime. And I have ran into this before: a compiler with a re
by Jasper_ 3y ago
Except constexpr isn't a guarantee. Compilers can choose to silently evaluate constexpr things at runtime. And I have ran into this before: a compiler with a recursion limit causing it to bail on constexpr and just emit the code.
So constexpr isn't a guarantee of it being evaluated at compile time, and non-constexpr isn't a guarantee of it being evaluated at runtime. Cool, huh?
- comex 3y agoC++20 has consteval and constinit to fix this (at the cost of making things even more complicated).
- MrBuddyCasino 3y agoAmazing.
- masklinn 3y agoMostly makes sense to me: constexpr means the function is evaluatable at compile-time, being callable at runtime is part of the contract and why adding constexpr does not change the API. For an assertion that something is evaluated at compile time I’d assume a variable-level annotation (in a non-constexpr function). Though I don’t know c++ enough to have any idea whether that’s the case. And contant evaluation optimisation has always been a thing so it’s not really surprising.
- Dylan16807 3y ago> Mostly makes sense to me: constexpr means the function is evaluatable at compile-time, being callable at runtime is part of the contract and why adding constexpr does not change the API. The problem isn't that you're able to call it at runtime with runtime data, it's that if you give it compile-time data you have no idea when it will be run. > For an assertion that something is evaluated at compile time I’d assume a variable-level annotation (in a non-constexpr function). Though I don’t know c++ enough to have any idea whether that’s the case. Oh, were you under the impression that constexpr was just for functions? It applies to variables too, and it's not a guarantee on them. You need to use other, newer annotations.
- jcelerier 3y ago> constexpr isn't a guarantee of it being evaluated at compile time constexpr is a guarantee that you can use the thing in a constexpr context, and this is where the "evaluated at compile-time" guarantee can come from: template<typename T> auto func() { // here some compilers can still choose to evaluate x at run-time - and very likely all of them if no optimizations are enabled constexpr int x = f(); // but here it becomes mandatory for this use of x to be evaluated at compile-time, since the number is literally going to be part of the compiled binary as part of the function name mangling return std::integral_constant<int, x>{}; }
- Dylan16807 3y agoIs such a mangling mandated by the standard?
- mhh__ 3y agoMangling is mentioned in the standard. In this case though the underlying reason is that its part of the type (system) not because of the mangle specifically.
- Dylan16807 3y ago> Mangling is mentioned in the standard. Forgive me, but can you be clearer than "mentioned"? Is the mangling required to contain template parameters for return types? > In this case though the underlying reason is that its part of the type (system) not because of the mangle specifically. I'm not sure. The compiler knows it will always be the same type, so under many uses of this function I could easily imagine a compiler that doesn't actually fill in .value until runtime.
- mhh__ 3y agoMangling isn't technically required as per se but it's by far the most common approach (basically a local minimum in terms of cost) I think this subset of C++ templates is probably undecidable still.