On 2017-01-13 14:29, Richard Smith wrote:
> On 13 January 2017 at 08:04, Matthew Woehlke wrote:
>> This presents an interesting case for having two attributes; one for
>> RAII things that just need to remain in scope for a non-trivial time,
>> and one for things the user *actually needs to inspect* (e.g. the result
>> of vector::empty()). Alas, that's not what we have. We may have missed
>> an opportunity there.
>
> Fortunately we're not stopping after C++17, so there'll be more
> opportunities :)
True. Moreover, I could rephrase that, "*should* we add an attribute
with this distinction?".
>> On 2017-01-12 20:48, Richard Smith wrote:
>>> You still seem to think this attribute is for something it's not for. A
>>> [[nodiscard]] call on the left-hand side of a comma should warn, because
>>> the value of that call was discarded. [[nodiscard]] says you must use the
>>> value, not that you must do something within the scope of the value.
>>
>> Maybe that was the *intent*, but that's *not* how I read the standard.
>> Particularly, there is a difference between assigning the value to a
>> variable that is not referenced again (especially if we ever get genuine
>> anonymous variables), and actually *doing something* with the value. I
>> guess we are relying on 'unused variable' warnings to catch that case?
>
> The handling of [[nodiscard]] is entirely a quality of implementation
> issue; if an implementation wants to check that the value is somehow used
> after being assigned to a variable, it is free to do so.
Agreed. The standard however seems to imply that assignment is
sufficient to satisfy that assignment is sufficient to satisfy
[[nodiscard]], since assignment is not a discarded-value expression (see
[dcl.attr.nodiscard] and especially [expr]/12).
That seems contrary to the intent, since the *intent* is that the user
actually does something with the result (usually, inspects it), and
merely assigning it doesn't accomplish that. OTOH, the compiler will
*probably* warn instead about an assigned but unused variable in such
cases. However...
>> (But then if we do get anonymous variables, we'll have to either change
>> how [[nodiscard]] is specified, or add such assignments to
>> discard-expressions.)
...there is this :-). For this reason, and also because it would be a
more targeted diagnostic, it may be useful to recommend that the value
is actually "used". (As you rightly point out, however, this is all
non-normative, so getting the standardese right is less crucial as long
as the actual compilers behave reasonably.)
>> I really think we should have two attributes with slightly different
>> semantics:
>>
>> - NODISCARD, which warns if the value so marked is immediately destroyed
>> at the conclusion of the statement which produced it.
>> - NOIGNORE, which warns if the value so marked does not participate in
>> any expression, excluding assignments.
>>
>> (Yes, I intend that assigning a NOIGNORE value to a non-local variable
>> should produce a warning... *if* the compiler can prove that said
>> variable is never used. I further expect compilers will err on the side
>> of optimism in the typical case that no such thing can be proved.)
>>
>> An alternate way of thinking about NOIGNORE is that the value must be
>> used as the parameter in some method or function, including calling
>> members of the value, but excluding copy and assignment operators.
>>
>> Of course, we can bikeshed names, including if [[nodiscard]] should be
>> NODISCARD or NOIGNORE (in which case maybe NODISCARD would be something
>> like [[nodestroy]]).
>
> Given that [[nodiscard]] was designed and is intended to mean what you call
> NOIGNORE, it would seem like a bad idea to change that now. Perhaps a
> better name for what you call NODISCARD would be [[raii]] or [[scope]] or
> similar?
Heh... here lies bikeshed territory. To me, "discard" means "drop on the
floor". Assigning something to a variable isn't "discarding", even if
you don't use it again. IOW, in a perfect world where I can ignore the
past, I would make [[nodiscard]] be NODISCARD, and would probably name
NOIGNORE [[noignore]].
Alas, we don't live in that world.
--
Matthew