Open lewissbaker opened 6 years ago
Cool question.
The design intent is for "coroutine-ness" to be stable in the presence of 'constexpr-if'. I'll check with CWG if we need to improve the wording to make it more explicit.
Rationale is partially flows from motivation and objections to if constexpr. For example, see: http://open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0128r0.html
Objections to 'constexpr if' were, essentially, that it is as bad as using the preprocessor to arbitrary cut and slice the body of the function. That objection was resolved with updated design which required compilers to look at discarded side as well.
Alterning the design will lead to code like:
template<typename T>
auto foo(T value) -> std::conditional<is_awaitable_v<T>, task<int>, int>
{
// Lots of common setup code here.
int x;
if constexpr (is_awaitable_v<T>)
{
// Only usage of co_await is here.
x = bar(co_await value);
}
else
{
x = bar(value);
}
if constexpr (is_awaitable_v<T>)
{
co_return x;
}
else
{
return x;
}
}
Which does not look like something we should encourage
Should we be supporting the ability for template functions to be conditionally compiled as coroutines in cases where one branch of an
if constexpr
branch contains theco_await
keyword and the other branch does not?For example: See https://godbolt.org/g/23jB2U
The current wording of N4680 8.4.4(1) says:
And N4713 9.4.1(2) says:
There seems to be some ambiguity of wording between these two sections as to whether or not a co_await/co_return/co_yield keyword that occurs within a statement discarded due to an
if constexpr
is still 'contained' within the function.@modocache Also found a potentially relevant precedence of wording from N4713 10.1.7.4(7):
This section is also using the term 'contains' but directly addresses the issue of whether or not statements discarded due to
if constexpr
should be considered by restricting it to consider only non-discarded return statements.Should the wording of N4680 8.4.4(1) be updated to also use the term non-discarded when referring to coroutine-return-statement, await-expression and yield-expression to allow interaction with
if constexpr
?Note that the current state of the Clang compiler (as of 2018/02/08) still triggers compilation of a function as a coroutine even if the only occurrences of the
co_xxx
keywords are within a discarded statement.