Hello,
Referring to the p1073r1 I was thinking about whether there makes sense in reducing resuability of code in order to be sure to execute the code in compile-time.
This seems to not be an issue at all, when there is constexpr! and non-constexpr! function defined, because we can provide optimized version of the code for runtime and
compile-time version for compile-time context.
I guess there still might be a use case of executing constexpr! function when it's non-constexpr! twin is not defined at all.
Maybe the function exists solely to do type computation
I don't understand the problem you're trying to solve
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d37bf67a-0a14-4143-b09a-87fe96b6f90b%40isocpp.org.
I thought, that instead of forbidding a function to be called at runtime at the definition, maybe it's better to introduce some calling syntax, that will help developer to force compile error if constexpr function is to be ran in runtime.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d37bf67a-0a14-4143-b09a-87fe96b6f90b%40isocpp.org.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJsLGmqgAg6xPs5H43jM8FMnJp6m-jL3j4u0snP1RrjxvzOQaA%40mail.gmail.com.
I don't like this idea.constexpr!, or immediate functions, are proposed because they are useful for reflections, where you might have to have a function that can only be called at compile-time because it does some reflection stuff. constexpr is not enough for it, as a constexpr function can also be called with runtime arguments, and you can't reflect on runtime stuff. Now you're saying to lift this requirement? That would mean that there would be no difference between constexpr and immediate functions. Also, I don't really like "constexpr overloading" because a constexpr function can also be called at runtime, there is no inherit reason to think that a constexpr function should only be called at runtime; I think a better idea for this is std::is_constant_evaluated() (P0595).
On Tuesday, August 7, 2018 at 12:41:51 AM UTC+2, Ville Voutilainen wrote:On 7 August 2018 at 01:26, Arthur O'Dwyer <arthur....@gmail.com> wrote:
> On Monday, August 6, 2018 at 1:49:25 PM UTC-7, Ville Voutilainen wrote:
>>
>> On 6 August 2018 at 23:23, Nicol Bolas <jmck...@gmail.com> wrote:
>> > By contrast, there can be times when the non-constexpr version is the
>> > same
>> > as the constexpr one, except that maybe it does some file logging. So
>> > doing
>> > an `if constexpr(!is_constant_evaluated())` to surround such blocks is
>> > perfectly valid.
>>
>> That condition is always false, so I don't know what you're getting at.
>
>
> Yes you do.
>
>
> There's an unfortunate tendency of several people in "constexpr" discussions
> to treat the accidental behavior of
That behavior is not accidental.Yes it's worse, it's confusing by design.
What's the motivation for this?
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4c8c5f38-7e00-4b6a-a46a-c942e3e0a534%40isocpp.org.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4c8c5f38-7e00-4b6a-a46a-c942e3e0a534%40isocpp.org.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJsLGmqiFSA4xZieB8Y-1%2BLzXbZKvBtMprr3W%3Deasf14rMB%2B0g%40mail.gmail.com.
Oh ok. Well, in that case, I would do:constexpr auto result = foo(/*args*/);so that foo is evaluated at compile-time. There's some talk about adding a constexpr compound statement, where everything in it would be constant evaluated so that would also solve your problem in a way (you might want to look into that).
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CALmDwq2KqeoV-_KgtNo%3Dcg8bRxELsY3b4f8WxS9fDHjJMwe%3DVQ%40mail.gmail.com.
@Nicolas LesserWhat's the motivation for this?
I will try to share with you my motivation.there can be some numerical computation done in the constexpr function. For me it's important, that in some usages it will be compile time evaluated, otherwise I cannot fulfill my agreement with the user regarding performance.
So now I want to call it
//context
my_contexpr_function_here(/*args*/);
//context
issues:
1. There is no way of checking whether the function really got executed in compile time,
2. There is no way if informing the reader (instead of the comment) to let him know that he must not break the compile-time evaluation of constexpr function.
So in my case after writing things down, to be sure, that function is compile-time evaluated I needed to check the generated code.
On Tuesday, August 7, 2018 at 1:41:17 AM UTC-4, Ville Voutilainen wrote:On 7 August 2018 at 03:51, Nicol Bolas <jmck...@gmail.com> wrote:
> In fact, looking over P0595, it's actually negatively useful as a feature.
> It is only allowed to evaluate to "true" in cases where the expression is
> required to be a constant expression; it must evaluate to "false" in other
> cases, even if the compiler wants to run it at compile time. So you cannot
> use it for cases where there is a divergence between efficient the
> compile-time and runtime solutions.
>
> So what good is the feature at all?
It gives you a portable result, as opposed to a result that depends on
whether your implementation
folds or not. Just use a normal if instead of if constexpr and it'll
do what you want.But that behavior is not "what I want".Basically, there are 3 possibilities in C++: required compile-time, implementation-dependent compile-time, and actual runtime.
This tool only allows us to distinguish between the first and the rest. What users need is to distinguish the last from the rest. After all, that's why you guard these blocks; they're for stuff that can't happen at compile-time/runtime, regardless of how the compiler decides when to run which.When exactly would I care about the difference between required compile-time and implementation-dependent compile-time? If I'm doing logging, which can't be done at compile time, I don't care why the function is being run at compile-time; I just need to not do logging in those cases.
For example, if you have some code that saysif (!nicol_bolas_is_constant_evaluated())my_logger << "something something\n";then is it your intent that the compiler is permitted to delete that if-statement and still execute the surrounding code at runtime? If not, why not? Does it matter if the logic inside the compiler that does this has something to do with its constant expression evaluator or is in a different piece of the compiler?
Or, in general, another reason we might want "if constexpr context" is so that we can use different algorithms at runtime versus compile-time — e.g., for performance reasons. See the example of "sqrt" worked out in https://quuxplusone.github.io/blog/2018/06/12/perennial-impossibilities/#detect-the-constexprness-of-the-current-context If the compiler had to instantiate both branches, it seems like that would tend to defeat the purpose.
Now, for a sufficiently smart compiler, there's a difference between instantiating both branches (which increases compile time) and codegenning both branches (which increases code size). Maybe that's what saves us here: all compilers will be sufficiently smart and we'll get the speed benefit on `sqrt` for only a mild compile-time hit. I'd like to see an implementation, though.(And yes, "constexpr context" is basically impossible to define. However, I think we're all worried about the WG21 equivalent of the Politician's Fallacy: "We must do something that is implementable — this is implementable — therefore we must do this.")
On Tuesday, August 7, 2018 at 1:53:14 AM UTC-4, Dawid Pilarski wrote:
@Nicolas Lesser
I will try to share with you my motivation.
there can be some numerical computation done in the constexpr function. For me it's important, that in some usages it will be compile time evaluated, otherwise I cannot fulfill my agreement with the user regarding performance.
So now I want to call it
//context
my_contexpr_function_here(/*args*/);
//context
issues:
1. There is no way of checking whether the function really got executed in compile time,
2. There is no way if informing the reader (instead of the comment) to let him know that he must not break the compile-time evaluation of constexpr function.
`constexpr!` handles both of those. You cannot call a `constexpr!` function with non-constexpr parameters, and the return value is always `constexpr`.
So in my case after writing things down, to be sure, that function is compile-time evaluated I needed to check the generated code.
`constexpr!` ensures that the function is compile-time evaluated.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/c515063f-8366-4ba0-bb80-17e98c10c245%40isocpp.org.
I guess that's my main issue with that `is_constexpr_context` proposal: is it solving a useful problem? What exactly is the code that a user needs to protect from required compile-time evaluation that would not also need protection from implementation-determined compile-time evaluation?
All of the examples given in the proposal are so abstract that they're meaningless. So what are the real-world examples of code where such determination is genuinely useful?Because we have cases where distinguishing between compile-time evaluation of any kind and runtime evaluation is useful. Things like using compiler intrinsics or inline assembly to do low-level things like sqrt and so forth. We want to be able to make such functions `constexpr`-callable, but the body of the `constexpr` version cannot use compiler intrinsics (presumably) or inline assembly. So you would condition which function gets called based on whether it is being evaluated at compile time.
string::string(char const* p, size_t len) {
if (is_constant_evaluated() || len > whatever) {
_buffer = new char[len + 1];
// ...
} else {
// SSO stuff
}
}It should also be noted that the `constexpr!` proposal doesn't talk about overloading. That is, there's nothing about what happens if you have two function declarations that differ only on the basis of `constexpr!`. So it doesn't seem to allow you to have two function bodies with the same name, such that the compiler will call one at compile-time and the other at runtime, based on how it gets used.
So even P1073 doesn't really give us this power.
On Wednesday, August 8, 2018 at 1:34:30 PM UTC-5, Nicol Bolas wrote:I guess that's my main issue with that `is_constexpr_context` proposal: is it solving a useful problem? What exactly is the code that a user needs to protect from required compile-time evaluation that would not also need protection from implementation-determined compile-time evaluation?All of the examples given in the proposal are so abstract that they're meaningless. So what are the real-world examples of code where such determination is genuinely useful?Because we have cases where distinguishing between compile-time evaluation of any kind and runtime evaluation is useful. Things like using compiler intrinsics or inline assembly to do low-level things like sqrt and so forth. We want to be able to make such functions `constexpr`-callable, but the body of the `constexpr` version cannot use compiler intrinsics (presumably) or inline assembly. So you would condition which function gets called based on whether it is being evaluated at compile time.It seems like you answered your question from your first paragraph in this paragraph? That's exactly what is_constant_evaluated() is for - to do one operation or the other (not which function gets called, but just what gets run in the body). It's not just about compiler intrinsics and stuff either, it's also to do something like... disable SSO when creating a std::string so that we can have constexpr std::strings. They don't have to be different functions, just in the body of the same function:string::string(char const* p, size_t len) {
if (is_constant_evaluated() || len > whatever) {
_buffer = new char[len + 1];
// ...
} else {
// SSO stuff
}
}
It should also be noted that the `constexpr!` proposal doesn't talk about overloading. That is, there's nothing about what happens if you have two function declarations that differ only on the basis of `constexpr!`. So it doesn't seem to allow you to have two function bodies with the same name, such that the compiler will call one at compile-time and the other at runtime, based on how it gets used.So even P1073 doesn't really give us this power.It just doesn't work that way.
#include <cstdlib>
constexpr int fib(int n) {
if (n < 0) std::abort();
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
static_assert(fib(7) == 13);
int f() { return fib(8); } // optimized to "return 21"
int g(int i) { return fib(i); }On Wednesday, August 8, 2018 at 6:31:17 PM UTC-4, Barry Revzin wrote:On Wednesday, August 8, 2018 at 1:34:30 PM UTC-5, Nicol Bolas wrote:I guess that's my main issue with that `is_constexpr_context` proposal: is it solving a useful problem? What exactly is the code that a user needs to protect from required compile-time evaluation that would not also need protection from implementation-determined compile-time evaluation?All of the examples given in the proposal are so abstract that they're meaningless. So what are the real-world examples of code where such determination is genuinely useful?Because we have cases where distinguishing between compile-time evaluation of any kind and runtime evaluation is useful. Things like using compiler intrinsics or inline assembly to do low-level things like sqrt and so forth. We want to be able to make such functions `constexpr`-callable, but the body of the `constexpr` version cannot use compiler intrinsics (presumably) or inline assembly. So you would condition which function gets called based on whether it is being evaluated at compile time.It seems like you answered your question from your first paragraph in this paragraph? That's exactly what is_constant_evaluated() is for - to do one operation or the other (not which function gets called, but just what gets run in the body). It's not just about compiler intrinsics and stuff either, it's also to do something like... disable SSO when creating a std::string so that we can have constexpr std::strings. They don't have to be different functions, just in the body of the same function:string::string(char const* p, size_t len) {
if (is_constant_evaluated() || len > whatever) {
_buffer = new char[len + 1];
// ...
} else {
// SSO stuff
}
}And what happens if the compiler wants to execute that at compile time in a non-constant expression context? It can't, because "SSO stuff" can't be executed at compile time. Whereas if `is_constant_evaluated` had returned true during non-constexpr compile time execution, it could have worked.
#include <cstring>
int n() {
float f = 5.0;
int i;
std::memcpy(&i, &f, sizeof(i));
return i; // optimizes to "return 1084227584"
}