Annex F (informative)
Core undefined behavior
[ub]
F.4
[stmt]
: Statements
[ub.stmt]
F.4.2
[ub:stmt.return.coroutine.flow.off]
Specified in:
[stmt.
return.
coroutine]
1
#
Flowing off the end of a coroutine function body that does not return
void
has undefined behavior
.
2
#
[
Example
1
:
#include
<
cassert
>
#include
<
coroutine
>
#include
<
iostream
>
#include
<
vector
>
class
resumable
{
public
:
struct
promise_type;
using
coro_handle
=
std
::
coroutine_handle
<
promise_type
>
; resumable
(
coro_handle handle
)
:
handle_
(
handle
)
{
assert
(
handle
)
;
}
resumable
(
resumable
&
)
=
delete
; resumable
(
resumable
&
&
)
=
delete
;
bool
resume
(
)
{
if
(
not handle_
.
done
(
)
)
handle_
.
resume
(
)
;
return
not handle_
.
done
(
)
;
}
~
resumable
(
)
{
handle_
.
destroy
(
)
;
}
const
char
*
return_val
(
)
;
private
:
coro_handle handle_;
}
;
struct
resumable
::
promise_type
{
using
coro_handle
=
std
::
coroutine_handle
<
promise_type
>
;
const
char
*
string_;
auto
get_return_object
(
)
{
return
coro_handle
::
from_promise
(
*
this
)
;
}
auto
initial_suspend
(
)
{
return
std
::
suspend_always
(
)
;
}
auto
final_suspend
(
)
noexcept
{
return
std
::
suspend_always
(
)
;
}
void
unhandled_exception
(
)
{
std
::
terminate
(
)
;
}
void
return_value
(
const
char
*
string
)
{
string_
=
string;
}
}
;
const
char
*
resumable
::
return_val
(
)
{
return
handle_
.
promise
(
)
.
string_;
}
resumable foo
(
)
{
std
::
cout
<
<
"Hello"
<
<
std
::
endl;
co_await
std
::
suspend_always
(
)
;
// undefined behavior, falling off the end of coroutine that does not return
void
}
int
main
(
)
{
resumable res
=
foo
(
)
;
while
(
res
.
resume
(
)
)
; std
::
cout
<
<
res
.
return_val
(
)
<
<
std
::
endl;
}
—
end example
]