C++ Logo

std-proposals

Advanced search

Re: [std-proposals] constraint that function can/shall be evaluated at compile time

From: Robin Savonen Söderholm <robinsavonensoderholm_at_[hidden]>
Date: Mon, 16 Sep 2024 08:03:18 +0200
Ok, thanks for the clarification. I feel that I learn more about C++ in
this forum (I thought the lifetime of '42' would end before the
dereferencing). But still, in these examples I would still argue that
'foo(...)' would be deemed constexpr in all cases, it is rather the return
value of 'foo()' that is not (constexpr dereferencing, but not it's
copy/move assignment or constructors, if they are called that for built-in
types).

// Robin

On Sun, Sep 15, 2024, 21:50 Lénárd Szolnoki <cpp_at_[hidden]> wrote:

>
>
> On 15/09/2024 20:17, Robin Savonen Söderholm wrote:
> > Ok, thank you both for your answers. Do I understand you correctly with
> > the "core constant expression" vs. "constant expression" that the former
> > means "unconditionally constexpr (given that arguments are available in
> > compile-time)" while the latter means "constexpr for some branch-path
> > depending on input parameter"?
>
> No, these are terms defined in the standard:
>
> https://eel.is/c++draft/expr.const#5 and
> https://eel.is/c++draft/expr.const#14
>
> The gist is that "core constant expressions" are the expressions that
> are allowed somewhere within constant evaluation, while "constant
> expressions" are the end result of such constant evaluations with
> additional constraints.
>
> For example:
>
> constexpr int* foo(int&& x) { return &x; }
>
> // foo(42) is allowed within constant evaluation,
> // that is foo(42) is a core constant expression
> constexpr auto x = *foo(42); // x is int with value 42
>
> // ERROR: pointer to temporary is not a constant expression,
> // therefore foo(42) is not a constant expression
> constexpr auto y = foo(42);
>
> The difference is subtle.
>
> This has nothing to do with unconditional behaviour, you can only
> reasonably reflect on either with fixed argument values.
>
> >
> > In that case I personally see 2 cases that are interesting (and perhaps
> > viable): the "unconditionally constexpr" and "constexpr given a specific
> > input". Having a concept say that "it may be constexpr for some input
> > but we don't know which" is probably not that useful, but I may
> be wrong...
> >
> > // Robin
> >
> > On Sun, Sep 15, 2024 at 6:22 PM Lénárd Szolnoki <cpp_at_[hidden]
> > <mailto:cpp_at_[hidden]>> wrote:
> >
> >
> >
> > On 15/09/2024 09:36, Robin Savonen Söderholm via Std-Proposals wrote:
> > > Hi!
> > >
> > > Another thing I found that I'd like in concepts is the notion
> > that e.g.
> > > a function related to a type can or shall be evaluated at compile
> > time.
> > > For example, this:
> > > ```c++
> > > template <typename T>
> > > concept has_foo = requires() {
> > > { T::foo() /*consteval*/ } -> is_foo_like;
> > > };
> >
> > Some of this is possible, although rather ugly.
> >
> > template <typename T>
> > concept has_foo = requires {
> > // T::foo() is a core constant expression
> > ( int(*)[((void)T::foo(), 1)] )nullptr;
> >
> > { T::foo() /*consteval*/ } -> is_foo_like;
> > };
> >
> > There are variations on this that are more or less ugly with
> different
> > trade-offs.
> >
> > It's worth noting that you can potentially reflect on two distinct
> > properties: whether an expression is a "core constant expression" or
> > whether it is a "constant expression", the latter being stricter. The
> > trick above reflects on the expression being a core constant
> expression.
> >
> > With a similar trick you can reflect on the expression being a
> constant
> > expression and structural. This is something you usually want if you
> > want to check if an expression is usable as a condition in `if
> > constexpr` for example.
> >
> > I'm not aware of a trick that allows you to reflect on an expression
> > with non-structural type being a "constant expression".
> >
> > I wouldn't be against a convenience syntax that allows reflecting on
> > these properties of expressions. But it is two distinct properties,
> > "core constant expression" and "constant expression".
> >
> > The limitations that Arthur outlined in his email apply too, you
> can't
> > really reflect on constexpr-ness and have unspecified arguments.
> >
> > > ```
> > > This is because I may want to use the result of `foo` to
> distinguish
> > > what kind of reflections I should be allowed to use on `T`, and
> what
> > > should be considered a compile error. I.e. I want to use it as:
> > > ```c++
> > > void bar(has_foo auto const& my_t) {
> > > if constexpr(T::foo(/*possible use of consteval arguments as
> > well*/) ==
> > > something_else) {
> > > do_foo_only_stuff(my_t);
> > > }
> > > }
> > > ```
> > >
> > > // Robin
> > >
> >
>

Received on 2024-09-16 06:03:32