[Development] C++20 ctor-level [[nodiscard]] (was: Re: C++20 @ Qt)
Volker Hilsheimer
volker.hilsheimer at qt.io
Sun Jun 18 14:59:26 CEST 2023
> On 16 Jun 2023, at 20:25, Thiago Macieira <thiago.macieira at intel.com> wrote:
>
> On Friday, 16 June 2023 11:05:30 PDT Giuseppe D'Angelo via Development wrote:
>> On 16/06/2023 18:00, Thiago Macieira wrote:
>>> On Friday, 16 June 2023 01:06:33 PDT Stephen Kelly wrote:
>>>> Make sure you're not hitting
>>>>
>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96117
>>>
>>> We are indeed hitting that. But there's nothing we can currently do about
>>> it.
>> Why can't we turn Q_DECL_EXPORT to [[gnu::visibility("default")]] to
>> work around the bug?
>
> Marc to comment, but I don't think it solves the MSVC problem we're also
> hitting, which means that adding no_discard to classes is still a problem.
> Therefore, there's no point in changing our Q_DECL_EXPORT.
>
> We'd also need to change *all* our __attributes__, not just the visibility
> ones, and we still risk breaking users' code that have __attributes__ in their
> classes and especially functions but use Q_DECL_EXPORT.
>
> Think of declarations like:
>
> [[nodiscard]] Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype qustrlen(const
> char16_t *str) noexcept;
My take-away is: What we should care about is the small set of RAII classes where the side-effects of the constructor and destructor are the whole point. E.g. it would be good if we can reliably encourage a compiler warning for Listing 1:
QMutexLocker(&mutex);
because that mistake is easily made and positively harmful.
From what I get out of this recap of the state of standard and compilers, it seems that we can't: class-level [[nodiscard]] doesn’t give us that warning (reliably, on all compilers), while it does give us warnings that we might not want (ie when not using the return value of a function). And it’s problematic to use with whole-sale exported classes; but since RAII types like QMutexLocker shouldn’t be exported whole-sale anyway, that’s perhaps not a problem in practice.
So, agree with Marc’s proposal to drop (or at least not add any new) usage of class-level [[nodiscard]], and to use constructor-level [[nodiscard]] instead via Q_NODISCARD_CTOR (*). This still makes it a good service to Qt users that are on C++ 20. For everyone else, things are as they were before.
For all other types, I think it’s quite alright that users writing code as per Marc's Listings 2-4:
QSize(12, 32);
have to figure out the “hard" way why there is no variable to pass into the function that they were planning on calling.
Volker
(*) That macro that does nothing until C++20 anyway, so I’d also add the support for the optional string-literal that C++20 also introduces..
More information about the Development
mailing list