3 ms·
but how will you differentiate a call that you want to perform at compile-time vs at run-time? e.g. if you want to run some unit tests to check the two algos, t
by jcelerier 5y ago
but how will you differentiate a call that you want to perform at compile-time vs at run-time? e.g. if you want to run some unit tests to check the two algos, today you'd do:
int res = my_algo();
CHECK(res == 123);
...
constexpr int res = my_algo();
CHECK(res == 123); // compile-time version is the same
with
int my_algo() {
if constexpr(is_constant_evaluated()) {
return 123;
else
return some_lib->very_advanced_computation();
}
how do you do the same without the constexpr keyword ? i'd rather not introduce a template struct just to get a constexpr context, à la
template<auto Value>
struct manually_constexpr { static constexpr auto value = Value; };
CHECK(manually_constexpr<my_algo()>::value == 123);
- petters 5y ago"constexpr" does not do what you think it does. For example, "if constexpr(is_constant_evaluated())" is always true, I think. See also the new C++ keyword "consteval" (yes, really!)
- jcelerier 5y agoah yes, that'll teach me to type on my phone :) what do you think that I think that constexpr does ? constexpr in a variable forces the variable's value to be evaluated in a constant expression context (which comes with footgunes, see an in-depth coverage of the issue there: https://gist.github.com/Som1Lse/5309b114accc086d24b842fd803ba9d2 https://gist.github.com/Som1Lse/5309b114accc086d24b842fd803b...)
- dataflow 5y ago> but how will you differentiate a call that you want to perform at compile-time vs at run-time? You could never do that to begin with. The compiler was always free to evaluate your function at compile time (and already did so in some cases). > e.g. if you want to run some unit tests to check the two algos Just make two separate functions and compare their outputs. That's what functions are for! So you don't put everything in one giant block of code. > i'd rather not introduce a template struct just to get a constexpr context, à la The standard library could do that for you instead of introducing a new keyword. In fact it practically already did so with std::integral_constant; they just need to update it for C++20 to avoid the redundancy. Or they could've introduced a [[pure]] attribute, or other less intrusive mechanisms. The keyword wasn't necessary for anything you mentioned. Also, as the sibling comment said, you might want to check out consteval.
- jcelerier 5y ago> You could never do that to begin with. The compiler was always free to evaluate your function at compile time (and already did so in some cases). no, that is false. the constant expression context is specified by the standard - the following will always hold if your compiler is not braindead : https://gcc.godbolt.org/z/zEEbWbhvr https://gcc.godbolt.org/z/zEEbWbhvr
- dataflow 5y ago>> You could never do that to begin with. The compiler was always free to evaluate your function at compile time (and already did so in some cases). > no, that is false. Your sentence is false, not mine. See below. > the constant expression context is specified by the standard Expressions can be evaluated at compile-time outside of "constant expression contexts", under the as-if rule. That's one of the main things compilers do when optimizing code.
- jcelerier 5y ago> Expressions can be evaluated at compile-time outside of "constant expression contexts", under the as-if rule. yes, but that does not make it a constexpr context, which is something explicitely specified by the standard. See my code example: the compiler is obviously able to evaluate foo() at compile time, yet it knows that the evaluation it does at compile time will yield a different result that the one it does in a constexpr context.
- dataflow 5y ago> yes, but that does not make it a constexpr context It seems like we're talking past each other here. You wrote "How will you differentiate a call that you want to perform at compile-time vs at run-time [without constexpr]?" And I've been replying to that by pointing out that your run-time code can still be evaluated at compile time even if you don't use constexpr. Heck, I'll point out now that it can still be evaluated at run-time even if you do use constexpr! [1] It's neither here nor there. Now you're talking about whether "constexpr contexts" do this, which is a separate question. Incidentally, even constexpr contexts don't distinguish between compile-time and run-time evaluation in anywhere except the condition itself [1], which is not the part you generally care the most about. If you want compile-time evaluation, you need to force its evaluation at a location where it's required to be evaluated at compile time, which is either a template parameter or a constexpr variable declaration. You seem to be desiring consteval when you talk about constexpr. (And you still haven't addressed the fact that your unit-test example is better served by having two separate functions!) > the compiler is obviously able to evaluate foo() at compile time, yet it knows that the evaluation it does at compile time will yield a different result that the one it does in a constexpr context. Citing this ability as if it's desirable is really strange. If your code does that it's buggy. A good language would outlaw this, not embrace it. [1] https://gcc.godbolt.org/z/Yhqvqz5Pc https://gcc.godbolt.org/z/Yhqvqz5Pc