Sorry, not sure how to reply to this thread only (probably because I set my mailing list subscription to "digest once per day").
> `if constexpr` has explicit rules allowing it to discard statements
> depending on the result of the constant expression. But that is a
> special grammatical construct explicitly designed with this
> functionality in mind.
This is exactly what I'm talking about. Why `if constexpr` can discard statements but boolean operations cannot?
I would imagine that the behaviour of the following two code snippets is identical:
```
if constexpr (a)
{
if constexpr (b)
{
//do something
}
}
```
```
if constexpr (a && b)
{
```
But it is not in the case where `a` is true and `b` is not evaluatable.
Of course, `b` should still be checked for basic syntax the same way templates are checked even before they're instantiated.
You cannot compile a template with broken syntax but you can still write a template which doesn't make sense for specific types as long as you don't instantiate the template with those types.
I think the same logic should apply here. `b` should be valid only if it is instantiated/evaluated. And this instantiation should only happen if the expression's value is needed (i.e. `a` was true).
This is what I refer to as "short-circuiting".
Think of it as a lazy evaluation.
If `a` is false the compiler should not even consider evaluating `b` and should not generate any compilation errors if `b` is not a valid expression.
I realize I'm complaining about syntactic sugar but syntactic sugar is sometimes needed to adhere to the DRY principle and in this case I think it would make the code more readable and less error-prone. Also, it would make the generic world look and feel more like the runtime world.
I would go even further and add a constexpr ternary operator, so you can reduce code duplication even more. But that's a totally different topic.
--
Zamfir Yonchev
Send Std-Discussion mailing list submissions to
std-discussion@lists.isocpp.org
To subscribe or unsubscribe via the World Wide Web, visit
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
or, via email, send a message with subject or body 'help' to
std-discussion-request@lists.isocpp.org
You can reach the person managing the list at
std-discussion-owner@lists.isocpp.org
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Std-Discussion digest..."
Today's Topics:
1. Re: short-circuiting logical operations on constexpr
predicates (Jason McKesson)
2. Re: short-circuiting logical operations on constexpr
predicates (Edward Catmur)
3. Re: short-circuiting logical operations on constexpr
predicates (Thiago Macieira)
----------------------------------------------------------------------
Message: 1
Date: Wed, 16 Nov 2022 09:42:58 -0500
From: Jason McKesson <jmckesson@gmail.com>
To: std-discussion@lists.isocpp.org
Subject: Re: [std-discussion] short-circuiting logical operations on
constexpr predicates
Message-ID:
<CANLtd3UfeDJ53Hm5zJXHUv0hNp-c=Yfn0Q6MTRzm=OeWiioNUw@mail.gmail.com>
Content-Type: text/plain; charset="UTF-8"
On Wed, Nov 16, 2022 at 5:00 AM Zamfir Yonchev via Std-Discussion
<std-discussion@lists.isocpp.org> wrote:
>
> Hi,
>
> I was wondering why the language doesn't support short-circuiting on logical operations in constexpr context.
It does. The rules of short-circuit evaluation don't change because
something is in a constant expression. Your problem is not a lack of
short-circuit evaluation; your problem is that short-circuit
evaluation doesn't mean what you think it does.
`std::invoke_result_t<F, T>` is ill-formed if `F` is not invokable.
That is not a matter of expression evaluation; that's a matter of
template instantiation. It's not the result of the evaluation that is
ill-formed; it's the *existence* of the expression itself. The literal
text of the source code makes no sense, as far as the language is
concerned. It is no different than if you wrote `a + - + - + c`.
The compiler doesn't get to the point where it would even consider
evaluating the expression because the code doesn't make sense.
`if constexpr` has explicit rules allowing it to discard statements
depending on the result of the constant expression. But that is a
special grammatical construct explicitly designed with this
functionality in mind.
So the reason why what you wrote doesn't work is because there is no
special expression-level construct that was added to the language to
allow discarding of subexpressions in the same way that `if constexpr`
can discard statements.
------------------------------
Message: 2
Date: Wed, 16 Nov 2022 15:02:26 +0000
From: Edward Catmur <ecatmur@googlemail.com>
To: std-discussion@lists.isocpp.org
Subject: Re: [std-discussion] short-circuiting logical operations on
constexpr predicates
Message-ID:
<CAJnLdOaTNma9xmW82jtKY0z4XYnBtCn++D5SyzARw37H6eCA1w@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
On Wed, 16 Nov 2022 at 14:44, Jason McKesson via Std-Discussion <
std-discussion@lists.isocpp.org> wrote:
> On Wed, Nov 16, 2022 at 5:00 AM Zamfir Yonchev via Std-Discussion
> <std-discussion@lists.isocpp.org> wrote:
> >
> > Hi,
> >
> > I was wondering why the language doesn't support short-circuiting on
> logical operations in constexpr context.
>
> It does. The rules of short-circuit evaluation don't change because
> something is in a constant expression. Your problem is not a lack of
> short-circuit evaluation; your problem is that short-circuit
> evaluation doesn't mean what you think it does.
>
> `std::invoke_result_t<F, T>` is ill-formed if `F` is not invokable.
> That is not a matter of expression evaluation; that's a matter of
> template instantiation. It's not the result of the evaluation that is
> ill-formed; it's the *existence* of the expression itself. The literal
> text of the source code makes no sense, as far as the language is
> concerned. It is no different than if you wrote `a + - + - + c`.
>
> The compiler doesn't get to the point where it would even consider
> evaluating the expression because the code doesn't make sense.
>
> `if constexpr` has explicit rules allowing it to discard statements
> depending on the result of the constant expression. But that is a
> special grammatical construct explicitly designed with this
> functionality in mind.
>
> So the reason why what you wrote doesn't work is because there is no
> special expression-level construct that was added to the language to
> allow discarding of subexpressions in the same way that `if constexpr`
> can discard statements.
>
Ahem. Actually, we do have such a construct in the evaluation of
constraints. You can make use of that mode by wrapping your test in
`requires requires`:
constexpr bool test = requires { requires std::is_invocable_v<F, T> &&
std::is_same_v<std::invoke_result_t<F, T>, int>; };
Demo: https://godbolt.org/z/7q5dvKnsn
https://eel.is/c++draft/expr.prim.req.general#5.sentence-3
-------------- next part --------------
HTML attachment scrubbed and removed
------------------------------
Message: 3
Date: Wed, 16 Nov 2022 11:17:22 -0800
From: Thiago Macieira <thiago@macieira.org>
To: std-discussion@lists.isocpp.org
Subject: Re: [std-discussion] short-circuiting logical operations on
constexpr predicates
Message-ID: <1805684.QCnGb9OGeP@tjmaciei-mobl5>
Content-Type: text/plain; charset="us-ascii"
On Wednesday, 16 November 2022 06:42:58 PST Jason McKesson via Std-Discussion
wrote:
> The literal
> text of the source code makes no sense, as far as the language is
> concerned. It is no different than if you wrote `a + - + - + c`.
Note, this expression *does* make sense and is allowed. The first + is the
binary addition operator; all the rest are unary prefixes. So this expression
is
a + (-(+(-(+c))))
If you remove the idempotent unary plus, you get
a + (-(-c))
And two negations is the same as doing nothing (ignoring the UB at INT_MIN),
resulting in a simple addition
a + c
Similarly, both a+++c and a---c are permitted, as are a*/*/*/c and a/*/*/*c.
None of those should pass a code review, of course.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel DCAI Cloud Engineering
------------------------------
Subject: Digest Footer
Std-Discussion mailing list
Std-Discussion@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
------------------------------
End of Std-Discussion Digest, Vol 44, Issue 3
*********************************************