Correction:
"A || B

If A is true, no runtime if statement occurs - C() does not need to be evaluated."

On Thu, 8 Apr 2021 at 12:39, Matthew Bentley <mattreecebentley@gmail.com> wrote:
I often come across this situation:

if (A && B)
{
    C();
}
else
{
    D();
}



But when A is constexpr, there is no way to indicate to the if statement that B is not also constexpr. Ideally the compiler would detect this and evaluate A at compile-time anyway, getting rid of the unused code, but in my experience with various compilers this is not usually the case and cannot be relied upon. Further, even the simplest workaround for enabling use of constexpr is ugly:

if constexpr (A)
{
    if (B)
    {
        C();
    }
    else
    {
        D();
    }
}
else
{
    D();
}



I would support a more flexible usage of 'if constexpr' ala the constexpr function guidelines, which allow for case-dependent runtime or compile-time calling.
Very specifically, where A is constexpr and B is not:


A && B

If A is true, an if statement based on B is evaluated at runtime - C() must be evaluated.
If A is false, no runtime if statement occurs - C() does not need to be evaluated.


A || B

If A is true, no runtime if statement occurs - C() must be evaluated.
If A is false, an if statement based on B is evaluated at runtime - C() must be evaluated.


More complex statements like A && B || X are supersets of the above.

If a non-situation-dependent constexpr if situation is still useful for various contexts, it could follow the lead of constexpr functions and use the consteval keyword instead.


Further, this would also simplify the situational rules when const**** if statements rely on the calling of C++20 constexpr functions. Put simply, a 'consteval if' could only take consteval functions as parameters. A 'constexpr if' could take either constexpr or consteval functions as parameters.

M@