On 3/22/23 16:01, Daniela Engert via Boost wrote:
> 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().
I did not mean to mark either of the functions as [[nodiscard]], I was
considering marking scope_exit as [[nodiscard]], which, I think, is what
you suggested. If it was marked as such, the code in bar() would emit a
warning, which I'm not sure is a good thing. For now I'm leaning towards
not marking the scope guards with [[nodiscard]] as I don't like limiting
the use cases of these classes.