C++ Logo


Advanced search

Subject: [std-proposals] Delay the judgement for coroutine function after the instantiation of template entity.
From: chuanqi.xcq (yedeng.yd_at_[hidden])
Date: 2021-01-20 00:48:25

Hi! I am Chuanqi Xu, a new compiler engineer, who is new to this community too. Remind me if I do anything wrong.

The following example shows my motivation.

template<bool UseCoro>
std::conditional_t<UseCoro, CoroType, ValueType>
func(ValueType v) {
    if constexpr (UseCoro)
        co_return v;
        return v;

I want to use constexpr-if grammer to make it possible that programmer could choose to use a normal function or a coroutine at compile time. However, both gcc and clang emit error for above example because we can't use `return` in a coroutine.

Then I find this behavior is desired by the standard. from N4878 says:
If the if statement is of the form if constexpr, the value of the condition shall be a contextually converted
constant expression of type bool (7.7); this form is called a constexpr if statement. If the value of the converted
condition is false, the first substatement is a discarded statement, otherwise the second substatement, if
present, is a discarded statement. During the instantiation of an enclosing templated entity (13.1), if the
condition is not value-dependent after its instantiation, the discarded substatement (if any) is not instantiated.

and from N4878 says:
A coroutine returns to its caller or resumer (9.5.4) by the co_return statement or when suspended (
A coroutine shall not enclose a return statement (8.7.4).
[Note 1 : For this determination, it is irrelevant whether the return statement is enclosed by a discarded statement
(8.5.2). —end note]

I think the Note in is a little bit odd. From my point of view, the logic is:
1. a function who contains one of `co_*` keywords is a coroutine.
2. a template function stands for a family of functions. Only a instantiated template function stands for a function.
3. From 1 and 2, we should judge whether a template function is a coroutine after it is instantiated.

So I am a little bit confusing why there is a note in And I think we should remove this constraint if there is no other special reasons.

I did a simple patch in clang which could make the example above to compile. So I think the implementation would not be very hard.

The reason why we want this feature is that my collegues find that: coroutine get great improvement in some situations while getting big regression in other situations.
As a compiler programmer, I think it is hard to optimize coroutine fast as normal function in all cases.
So I think it would be a solution that programmer could choose to use a coroutine function or a normal function at compile time.

STD-PROPOSALS list run by std-proposals-owner@lists.isocpp.org

Standard Proposals Archives on Google Groups