Date: Mon, 9 Oct 2023 10:49:06 +0200
Hello,
On 06/10/2023 16:23, Arthur O'Dwyer wrote:
> On Fri, Oct 6, 2023 at 9:45 AM Giuseppe D'Angelo via Std-Proposals
> <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>>
> wrote:
>
> On 06/10/2023 11:30, Ferhat Geçdoğan via Std-Proposals wrote:
> > Is there any useful use-case that makes [[discard]] unique?
> That's just
> > a way of adding one more unuseful C++ keyword to the list in my
> opinion.
>
> It's not a new keyword, it's an attribute.
>
>
> But if EWG thinks it "has an effect," they'll ask to make it a keyword. ;)
I'm not really sure what this means? [[nodiscard]] "has the effect" of
raising a warning in certain contexts, [[discard]] "has the effect" of
suppressing that warning. Why should they be different?
>
> * It does not abuse the cast notation and the cast semantics towards
> void in order to suppress a warning. Doing a cast to void (à la
> `(void)f();`) isn't done because one wants a specific type conversion,
> it's done to silence the [[nodiscard]] warning.
>
>
> Well, it occurred to me this morning that (void) has another very nice
> synergy. Remember how we said yesterday that nobody should ever use the
> comma operator for anything? Well, today I'm walking back from that
> position a little bit. Library implementors use it a lot, in the context
> of the three-part for loop:
> for (int i = 0; i < n; ++i, (void)update(n))
> In this context, (void) has two reasons to exist:
> - It indicates that we're discarding the value of `update` (which let's
> assume is a user-provided function that the library doesn't know what it
> returns)
> - It suppresses ADL on that `operator,` in case the user-provided
> `advance` returns some type `Evil`
> struct Evil { friend void operator,(int, Evil) { puts("ha ha"); } };
>
> That is, (void) coincidentally-or-not fits the bill for these library
> implementors exactly.
I would argue that this is actually conflating the meanings. Here you're
showing how to use a cast to void to disable a possible user-provided
operator,. That's perfectly fine! You *do* want to change the type of
`update(n)`, because of ADL fears, and a cast to void is perfectly
adequate to that job.
But you're *also* suppressing the nodiscard warning. Did you intend to
do that, or was it an accidental by-product of the cast to void? What if
that is hiding a bug?
My point is that in a statement like
(void)f();
you don't really want to cast/change the type of anything; you just want
to suppress the warning. This is where I think that the cast notation is
a notation abuse. Blessed by everyone, by still, an abuse.
If you want to conceptually split the casting from the warning
suppression, in the example above, you could just write something like:
for (int i = 0; i < n; ++i, (void)update(n) [[discard]])
or
for (int i = 0; i < n; ++i, ([[discard]] (void)update(n)))
> Your proposed [[discard]] wouldn't be a replacement for (void) here.
> So, if I value consistency and having-a-small-subset-of-C++-to-teach,
> and I have to teach (void) here,[*] I don't see why I should teach a
> different syntax anywhere else.
> [* — Teach to library contributors and other advanced folks; obviously
> not teach on Day 2 of the intro course. :)]
Yes, and can digest this and countless other advanced stuff. I'm not
really catering to the "top" x% of C++ developers...
> IMO the paper should mention this use of comma, even if only to dismiss
> it as "not relevant because this is not a place the compiler would warn
> anyway" or "there are better ways to write this" or whatever. Just get
> the whole question out of the way, one way or another.
I'm not sure what to say here; people use comma operators when they're
otherwise ... constrained by the C++ syntax? :) Unrolling a for loop's
head is certainly possible, but extremely verbose; solution: operator
comma! You can still [[discard]] it.
Thank you,
On 06/10/2023 16:23, Arthur O'Dwyer wrote:
> On Fri, Oct 6, 2023 at 9:45 AM Giuseppe D'Angelo via Std-Proposals
> <std-proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>>
> wrote:
>
> On 06/10/2023 11:30, Ferhat Geçdoğan via Std-Proposals wrote:
> > Is there any useful use-case that makes [[discard]] unique?
> That's just
> > a way of adding one more unuseful C++ keyword to the list in my
> opinion.
>
> It's not a new keyword, it's an attribute.
>
>
> But if EWG thinks it "has an effect," they'll ask to make it a keyword. ;)
I'm not really sure what this means? [[nodiscard]] "has the effect" of
raising a warning in certain contexts, [[discard]] "has the effect" of
suppressing that warning. Why should they be different?
>
> * It does not abuse the cast notation and the cast semantics towards
> void in order to suppress a warning. Doing a cast to void (à la
> `(void)f();`) isn't done because one wants a specific type conversion,
> it's done to silence the [[nodiscard]] warning.
>
>
> Well, it occurred to me this morning that (void) has another very nice
> synergy. Remember how we said yesterday that nobody should ever use the
> comma operator for anything? Well, today I'm walking back from that
> position a little bit. Library implementors use it a lot, in the context
> of the three-part for loop:
> for (int i = 0; i < n; ++i, (void)update(n))
> In this context, (void) has two reasons to exist:
> - It indicates that we're discarding the value of `update` (which let's
> assume is a user-provided function that the library doesn't know what it
> returns)
> - It suppresses ADL on that `operator,` in case the user-provided
> `advance` returns some type `Evil`
> struct Evil { friend void operator,(int, Evil) { puts("ha ha"); } };
>
> That is, (void) coincidentally-or-not fits the bill for these library
> implementors exactly.
I would argue that this is actually conflating the meanings. Here you're
showing how to use a cast to void to disable a possible user-provided
operator,. That's perfectly fine! You *do* want to change the type of
`update(n)`, because of ADL fears, and a cast to void is perfectly
adequate to that job.
But you're *also* suppressing the nodiscard warning. Did you intend to
do that, or was it an accidental by-product of the cast to void? What if
that is hiding a bug?
My point is that in a statement like
(void)f();
you don't really want to cast/change the type of anything; you just want
to suppress the warning. This is where I think that the cast notation is
a notation abuse. Blessed by everyone, by still, an abuse.
If you want to conceptually split the casting from the warning
suppression, in the example above, you could just write something like:
for (int i = 0; i < n; ++i, (void)update(n) [[discard]])
or
for (int i = 0; i < n; ++i, ([[discard]] (void)update(n)))
> Your proposed [[discard]] wouldn't be a replacement for (void) here.
> So, if I value consistency and having-a-small-subset-of-C++-to-teach,
> and I have to teach (void) here,[*] I don't see why I should teach a
> different syntax anywhere else.
> [* — Teach to library contributors and other advanced folks; obviously
> not teach on Day 2 of the intro course. :)]
Yes, and can digest this and countless other advanced stuff. I'm not
really catering to the "top" x% of C++ developers...
> IMO the paper should mention this use of comma, even if only to dismiss
> it as "not relevant because this is not a place the compiler would warn
> anyway" or "there are better ways to write this" or whatever. Just get
> the whole question out of the way, one way or another.
I'm not sure what to say here; people use comma operators when they're
otherwise ... constrained by the C++ syntax? :) Unrolling a for loop's
head is certainly possible, but extremely verbose; solution: operator
comma! You can still [[discard]] it.
Thank you,
-- Giuseppe D'Angelo
Received on 2023-10-09 08:49:11