rspec/rules/S6391/cfamily/rule.adoc
Marco Borgeaud 072e67b8d4
Fix asciidoc w.r.t. C++ (#3519)
"C++" spelled as-is can result in unexpected rendering, such as

    C++20 was released before C++17

renders as

    C20 was released before C17

Make consistent use of `[source,cpp]`.
2023-12-21 15:51:41 +01:00

57 lines
1.9 KiB
Plaintext

== Why is this an issue?
Coroutines, introduced in {cpp}20, are functions in which execution can be suspended and resumed.
When a coroutine resumes, it takes over where it left thanks to the coroutine state.
A _coroutine state_ is an object which contains all the information a coroutine needs to resume its execution correctly:
local variables, copy of the parameters...
This means that if a coroutine has a parameter that is a reference to an object, this object must exist as long as the coroutine is not destroyed.
Otherwise, the reference stored in the _coroutine state_ will become a dangling reference and will lead to undefined behavior when the coroutine resumes.
The issue is raised for all coroutine parameters with reference-to-const semantics
(such as a `const` reference, a `std::string_view`, or a `std::span` with `const` elements)
that might be used after the coroutine is suspended.
To fix the issue, you can either pass the parameter by value,
or not use the parameter after the first suspension point (`co_await`, `co_yield`, or `initial_suspend`).
=== Noncompliant code example
[source,cpp]
----
generator<char> spell(const std::string& m) { // Noncompliant
for (char letter : m) {
co_yield letter;
}
}
void print() {
for (char letter : spell("hello world")) { // Here the parameter "m" binds to a temporary
std::cout << letter << '\n'; // and becomes dangling on the next iteration
}
}
----
=== Compliant solution
[source,cpp]
----
generator<char> spell(const std::string m) { // Compliant: take the argument by copy
for (char letter : m) {
co_yield letter;
}
}
void print() {
for (char letter : spell("hello world")) {
std::cout << letter << '\n';
}
}
----
=== Exceptions
This rule does not raise an issue for `std::reference_wrapper` parameters
taking it as a witness of the care taken to prevent the reference to become dangling.