[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