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.
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
> 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.
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.
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.
right, I should have wrote "in a constexpr context", e.g. what you find in template<invocations>, etc.
> 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.
I don't understand what this does have to do with the rest. That's just an optimization (which is not "consistently observable" and depends on the whims of the compiler). Making a variable constepxr is something that causes consistently observable results, which is much more useful. Incidentally, I have had multiple cases where things that could obviously be computed at compile-time weren't optimized in such a way by clang or gcc unless I did
constexpr auto foo() { constexpr auto bar = some_complicated_function(...); return bar; }
instead of constexpr auto foo() { return some_complicated_function(...); }
with constexpr, if the compiler cannot compute the thing at compile time I get an error (which is good !)> You seem to be desiring consteval when you talk about constexpr.
what I actually desire deep down is a way to have aribtrary parametrisable contexts, something like a generalized version of http://www.jot.fm/issues/issue_2008_03/article4/ ; having two is already a good start.
> (And you still haven't addressed the fact that your unit-test example is better served by having two separate functions!)
well, because I disagree. If the name my function is e.g. strlen I definitely don't want a strlen_constexpr and strlen_nonconstexpr pair of functions, I want the good choice to be made depending on the context I'm in ; I want to write "strlen" in generic code and have the correct thing happen no matter what.
to give you my general perspective, constexpr could call itself super_bamboozle that I couldn't care less, I just want "multiple worlds" being available in my programming language. what name they take is of very little importance.
I actually wholeheartedly agree with that. I've wanted something pretty similar for a long time. I just also wholeheartedly disagree on constexpr having been a good start on that.
> Incidentally, I have had multiple cases where things that could obviously be computed at compile-time weren't optimized in such a way by clang or gcc unless I did [...]
And this is one place we circle back to my argument, which is that implicit constexpr should be the default wherever possible. That way you don't e.g. run into situations where you forgot the keyword by accident, because you won't need it to begin with.
> well, because I disagree. If the name my function is e.g. strlen I definitely don't want a strlen_constexpr and strlen_nonconstexpr pair of functions, I want the good choice to be made depending on the context I'm in ; I want to write "strlen" in generic code and have the correct thing happen no matter what.
I think you misunderstood the proposal then. I was saying those functions would be only called directly for tests. Everywhere else, you'd use your strlen() with std::is_constant_evaluated() (or whatever) dispatching to one of those two functions, which would be implementation details hidden away from the user.
For example, "if constexpr(is_constant_evaluated())" is always true, I think.
See also the new C++ keyword "consteval" (yes, really!)
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/5309b114accc086d24b842fd803b...)