Date: Thu, 24 Jul 2025 11:37:19 -0400
You may not have the source, only a header and the library file. The
attribute can be placed in the header to say the function returns the input
parameter & or a part of it OR on a constructor to say the class captures
the input parameter & or a portion of it.
On Thu, Jul 24, 2025 at 11:18 AM Jeremy Rifkin via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> Why is an attribute needed for this? Why not rely on static analysis tools?
>
> Jeremy
>
> On Tue, Jul 22, 2025 at 06:05 Frederick Virchanza Gotham via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
>
>> Sometimes we want the return value from a function not only to not be
>> discarded, but more specifically we want it to be stored inside a
>> local variable.
>>
>> Consider a method like std::synchronized_value::rlock, which returns
>> by value a type similar to "std::lock_guard". We always want this
>> return value to be stored in a variable:
>>
>> auto mylock = mysyncvalue.wlock();
>>
>> If the programmer is only going to call one method on it, then they
>> should instead use "operator->", therefore we can consider the
>> following to be incorrect:
>>
>> mysyncvalue.wlock()->DoSomething();
>>
>> and instead it should be replaced with:
>>
>> mysyncvalue->DoSomething();
>>
>> Therefore, it would make sense to mark the 'wlock' method as
>> [[must_store]].
>>
>> Another example is the wxWidgets library, with the class wxString. The
>> method, "wxString::c_str" looks like this:
>>
>> wxCStrData wxString::c_str() const
>> {
>> return wxCStrData(this);
>> }
>>
>> When you invoke "c_str" on a wxString object, it returns a wxCStrData
>> object. The wxCStrData class has two implicit conversions:
>>
>> operator const wchar_t*() const { return AsWChar(); }
>> operator const char*() const { return AsChar(); }
>>
>> If you build the wxWidgets library in Unicode mode, then the method
>> "AsWChar" returns a pointer to a pre-existing array. However if you
>> build the wxWidgets library in ASCII mode, and then invoke "AsWChar",
>> it dynamically allocates a temporary array and gives you the pointer.
>> This could allow us to put a very interesting bug into our code:
>>
>> wxString mystr( wxS("Hello I'm a monkey") );
>>
>> wchar_t *const p = mystr.c_str();
>>
>> wcout << p << endl;
>>
>> The above code will work fine on Unicode, but might crash on ASCII.
>> The dynamically-allocated array gets destroyed when "c_str()" returns.
>> The solution is to do this:
>>
>> wxString mystr("Hello I'm a monkey");
>>
>> auto const converter = mystr.c_str();
>> wchar_t *const p = converter;
>>
>> wcout << p << endl;
>>
>> If we can mark a function as [[must_store]] then it will prevent stuff
>> like this from making its way into the release build.
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
attribute can be placed in the header to say the function returns the input
parameter & or a part of it OR on a constructor to say the class captures
the input parameter & or a portion of it.
On Thu, Jul 24, 2025 at 11:18 AM Jeremy Rifkin via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> Why is an attribute needed for this? Why not rely on static analysis tools?
>
> Jeremy
>
> On Tue, Jul 22, 2025 at 06:05 Frederick Virchanza Gotham via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
>
>> Sometimes we want the return value from a function not only to not be
>> discarded, but more specifically we want it to be stored inside a
>> local variable.
>>
>> Consider a method like std::synchronized_value::rlock, which returns
>> by value a type similar to "std::lock_guard". We always want this
>> return value to be stored in a variable:
>>
>> auto mylock = mysyncvalue.wlock();
>>
>> If the programmer is only going to call one method on it, then they
>> should instead use "operator->", therefore we can consider the
>> following to be incorrect:
>>
>> mysyncvalue.wlock()->DoSomething();
>>
>> and instead it should be replaced with:
>>
>> mysyncvalue->DoSomething();
>>
>> Therefore, it would make sense to mark the 'wlock' method as
>> [[must_store]].
>>
>> Another example is the wxWidgets library, with the class wxString. The
>> method, "wxString::c_str" looks like this:
>>
>> wxCStrData wxString::c_str() const
>> {
>> return wxCStrData(this);
>> }
>>
>> When you invoke "c_str" on a wxString object, it returns a wxCStrData
>> object. The wxCStrData class has two implicit conversions:
>>
>> operator const wchar_t*() const { return AsWChar(); }
>> operator const char*() const { return AsChar(); }
>>
>> If you build the wxWidgets library in Unicode mode, then the method
>> "AsWChar" returns a pointer to a pre-existing array. However if you
>> build the wxWidgets library in ASCII mode, and then invoke "AsWChar",
>> it dynamically allocates a temporary array and gives you the pointer.
>> This could allow us to put a very interesting bug into our code:
>>
>> wxString mystr( wxS("Hello I'm a monkey") );
>>
>> wchar_t *const p = mystr.c_str();
>>
>> wcout << p << endl;
>>
>> The above code will work fine on Unicode, but might crash on ASCII.
>> The dynamically-allocated array gets destroyed when "c_str()" returns.
>> The solution is to do this:
>>
>> wxString mystr("Hello I'm a monkey");
>>
>> auto const converter = mystr.c_str();
>> wchar_t *const p = converter;
>>
>> wcout << p << endl;
>>
>> If we can mark a function as [[must_store]] then it will prevent stuff
>> like this from making its way into the release build.
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2025-07-24 15:37:36