Date: Wed, 20 Jan 2021 14:48:25 +0800
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;
else
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.
8.5.2.2 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 8.7.5.1 from N4878 says:
```
A coroutine returns to its caller or resumer (9.5.4) by the co_return statement or when suspended (7.6.2.4).
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 8.7.5.1 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 8.7.5.1. 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.
Thanks,
Chuanqi
The following example shows my motivation.
```
template<bool UseCoro>
std::conditional_t<UseCoro, CoroType, ValueType>
func(ValueType v) {
if constexpr (UseCoro)
co_return v;
else
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.
8.5.2.2 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 8.7.5.1 from N4878 says:
```
A coroutine returns to its caller or resumer (9.5.4) by the co_return statement or when suspended (7.6.2.4).
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 8.7.5.1 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 8.7.5.1. 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.
Thanks,
Chuanqi
Received on 2021-01-20 00:48:31