DIP 1038: @nodiscard - Unofficial "post-final" review

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sat Feb 27 13:31:19 UTC 2021

On 2/22/21 6:32 PM, Paul Backus wrote:
> On Monday, 22 February 2021 at 22:01:01 UTC, Andrei Alexandrescu wrote:
>> This is nice and well argued. The time-tested presence of the 
>> attribute in C++ is important, probably could use 1-2 paragraphs to 
>> emphasize that. (It's been a non-standard extension for a long time 
>> and clearly there was a lot of demand to standardize it.)
> Are there any well-known [[nodiscard]] success stories that the DIP 
> could cite? I have little personal experience with C++, and do not know 
> where to look for examples outside of the standard library.

Couldn't find an article specifically discussing a success story, but 
those are not easy to find quickly. One thing good to cite is that 
implementers do deprecate/ignore unsuccessful attributes (e.g. gcc had a 
"returns" attribute for a while indicating that a function returns a 
specific parameter, which was superseded by better RVO implementation in 
the compiler). Au contraire, noreturn was present in all major compilers 
and graduated to standardization. This only happens to useful attributes.

There's even an enhancement to it that you may also want to consider: 

>> void* malloc(size_t);
>> @nodiscard void* malloc(size_t);
>> I forgot what we usually do. I think it's safe to mark that as as error.
> @nodiscard is a user-defined attribute, and the compiler currently 
> allows multiple declarations of a function that differ only by UDAs. [1] 
> Again, I agree that this should probably be an error, but since it is an 
> issue that affects UDAs in general, it should be addressed in a Bugzilla 
> issue, not DIP 1038.

Hm, bit of a bummer.

> The way to achieve the outcome you desire here is to apply @nodiscard to 
> the method's return type, rather than the method itself:
>      @nodiscard struct Result { int unwrap; }
>      class A { Result func() { return Result(1); } }
>      class B : A { override Result func() { return Result(2); } }
> The idea behind the proposed design is that if you want strong 
> guarantees, you should be applying @nodiscard to your types, not to your 
> functions. If you are willing to accept weaker guarantees in return for 
> greater ease-of-use, that's when you should use @nodiscard as a function 
> attribute. (This design is cribbed from Rust's `#[must_use]` attribute, 
> which works the same way.)
> Of course, the fact we're having this exchange means that the above 
> explanation really ought to be in the DIP itself.

Yah, would be great to include such considerations, and now you've 
already done most of the work.

More information about the Digitalmars-d mailing list