From: Daniela Engert (dani_at_[hidden])
Date: 2023-03-22 13:01:18


Am 22.03.2023 um 13:34 schrieb Andrey Semashev via Boost:
> On 3/22/23 14:23, Daniela Engert via Boost wrote:
>> Am 22.03.2023 um 11:24 schrieb Andrey Semashev via Boost:
>>> [[nodiscard]] is not usable here as there's nothing to apply it to, as
>>> we're talking about the scope guard constructor.
>> [[nodiscard]] is highly desirable here. You can apply the attribute to
>> class types (and thus their constructors) and avoid the (typically
>> unwanted) immediate destruction of pr-values. Manager classes should be
>> marked [[nodiscard]] by habit.
> I didn't know you can apply [[nodiscard]] to classes, but apparently you
> can. I suppose, I could mark scope guards with it, but I'm not sure if
> limiting the use cases would be desirable. For example, should we
> consider the following a wrong use of the scope guard?
>
> auto foo()
> {
> // do something useful and return the epilogue
> return scope_exit([] { whatever });
> }
>
> void bar()
> {
> foo(); // do what foo() does, plus the epilogue
> // ...
> }
>
> void zoo()
> {
> auto epilogue = foo(); // do what foo() does, and delay the epilogue
> // ...
> }

Suppose you mark class scope_exit with [[nodiscard], then the return
statement in foo() will construct a temporary scope_exit in its return
expression and pass it out of function foo. This by itself is a use of
the temporary and doesn't trigger a compiler warning. If you want to
prevent the immediate destruction of the returned scope_exit in bar(),
then you need to mark foo() as [[nodiscard]]. But if you consider this a
valid use case (albeit a strange one) then you might want to mark foo()
as [[maybe_unused]] to communicate this intent. Remember: the return
object of foo() is conceptually different from the object created in the
return expression of foo().