Date: Tue, 4 Oct 2022 10:47:36 +0200
On Mon, 3 Oct 2022, 19.52 Jonathan Wakely via Lib, <lib_at_[hidden]>
wrote:
>
>
> On Mon, 3 Oct 2022, 18:21 Patrice Roy via Lib, <lib_at_[hidden]>
> wrote:
>
>> Yeah, floated the idea of exposing the size at which SBO threshold is
>> set (through traits or something similar) thinking this would do the job
>> (people could use std::function on their own function objects and
>> static_assert on that object's size begin sufficiently small), but this did
>> not get much traction yet; there seems to be more appetite (if I read
>> SG14's wishes well) for a never-allocating cousin of std::function, at
>> least so far... Discussions on this topic are not closed yet, so we'll see.
>>
>
>
> What about making the constructor conditionally noexcept? The
> implementation knows whether a given type will be stored on the heap, and
> if that type can be constructed without throwing, so can easily expose that.
>
> What people care about is a property of the constructor, so why not make
> it part of the constructor signature?
>
> You can static assert is_nothrow_constructible.
>
One problem is that you would need to wrap it in something to make it
usable. Because lambdas are unutterable unique types you can't cleanly
separate the construction of the function from the static assertion,
especially if you want to stay in expression space (I hate reading code
that declares used-once lambda variables rather than defining them in the
argument position).
If you had that, you could easily declare a subclass of std::function which
only declared a forwarding constructor with the nothrow constraint. I think
that would make it a lot more ergonomic. But then that raises the question
of if you need to do that for it to be usable (in some domains) why not
just standardize std::noalloc_function (and noalloc_unique_function I
guess) so it can be used as a vocab type?
That said, we've made our implementation of UniqueFunction always allocate
and just hold a unique_ptr<Impl> because a) the smaller object and cheaper
moves are nice if you have a fast allocator, and b) we found it was very
common for lambdas to capture std::functions/UniqueFunctions, which means
that no matter how big the SBO size it would need to allocate anyway. So we
wouldn't have a use for that type, although I understand that others have
different tradeoffs that would make it indispensable.
>
>> Le lun. 3 oct. 2022 à 12:40, Ben Craig <ben.craig_at_[hidden]> a écrit :
>>
>>> Are there any examples of implementations that cause allocations,
>>> syscalls, or non-deterministic behavior for std::function when it is used
>>> with a function pointer, stateless lambda, or std::reference_wrapper? Is
>>> that std::function implementation claiming to be standards conforming?
>>>
>>> Best I can tell, std::function is already specified to meet these
>>> requirements as best as can be done with the current specification
>>> techniques.
>>>
>>> My suspicion is that the reluctance to use std::function is based off of
>>> some combination of general STL fear, and possibly some other requirements
>>> (e.g. user controllable small buffer optimization (SBO) instead of
>>> implementation tuned SBO).
>>>
>>>
>>>
>>> *From:* Lib <lib-bounces_at_[hidden]> *On Behalf Of *Björn
>>> Andersson via Lib
>>> *Sent:* Monday, October 3, 2022 11:58 AM
>>> *To:* sg14_at_[hidden]
>>> *Cc:* Björn Andersson <bjorn.andersson_at_[hidden]>; lib_at_[hidden];
>>> Patrice Roy <patricer_at_[hidden]>
>>> *Subject:* [EXTERNAL] Re: [isocpp-lib] [SG14] std::function
>>>
>>>
>>>
>>> Den ons 21 sep. 2022 kl 03:07 skrev Patrice Roy via SG14 <
>>> sg14_at_[hidden]>:
>>>
>>> Indeed, this type is part of a set of requests SG14 is working on these
>>> days.
>>>
>>>
>>>
>>> The problem (for low-latency people) is that there's no programmatic way
>>> to know, in user code, if a given std::function instantiation will or will
>>> not allocate, so that makes this type unusable for some use cases (in
>>> particular, many game development companies will not touch std:function
>>> precisely for this reason; they don't just need an optimization, they need
>>> a guarantee).
>>>
>>>
>>>
>>>
>>>
>>> Incidentally, this is exactly what the safety-critical people need as
>>> well: Not just the performance, but the guarantee of no
>>> syscall/deterministic behaviour.
>>>
>>>
>>>
>>> Thanks,
>>>
>>> Björn
>>>
>>>
>>>
>>>
>>>
>>> Cheers!
>>>
>>>
>>>
>>> Le mar. 20 sept. 2022 à 12:19, Arthur O'Dwyer via Lib <
>>> lib_at_[hidden]> a écrit :
>>>
>>> On Tue, Sep 20, 2022 at 9:22 AM Bjarne Stroustrup via Lib <
>>> lib_at_[hidden]> wrote:
>>>
>>> I thought we had a variant of std::function that didn't allocate on free
>>> store for simple functions; it didn't make it for C++20? Is it still in
>>> process? and if so where would I look for the current state of the
>>> proposal.
>>>
>>>
>>>
>>> [cc: SG14]
>>>
>>> SG14 has implemented, and I maintain, a type-erased
>>> `stdext::inplace_function<void(), Capacity, Align>` based on an informal
>>> proposal by Carl Cook in 2016:
>>>
>>> https://github.com/WG21-SG14/SG14/blob/master/SG14/inplace_function.h
>>> <https://urldefense.com/v3/__https:/github.com/WG21-SG14/SG14/blob/master/SG14/inplace_function.h__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDabzpusS$>
>>>
>>>
>>> https://github.com/Quuxplusone/SG14/blob/ajo/include/sg14/inplace_function.h
>>> <https://urldefense.com/v3/__https:/github.com/Quuxplusone/SG14/blob/ajo/include/sg14/inplace_function.h__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDVgSckTs$>
>>>
>>>
>>> https://groups.google.com/a/isocpp.org/g/std-proposals/c/vven2Om7Ha8/m/C7qQ_XwVCwAJ
>>> <https://urldefense.com/v3/__https:/groups.google.com/a/isocpp.org/g/std-proposals/c/vven2Om7Ha8/m/C7qQ_XwVCwAJ__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDQVrHXUy$>
>>>
>>>
>>> https://github.com/WG21-SG14/SG14/blob/master/Docs/Proposals/NonAllocatingStandardFunction.pdf
>>> <https://urldefense.com/v3/__https:/github.com/WG21-SG14/SG14/blob/master/Docs/Proposals/NonAllocatingStandardFunction.pdf__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDZ7r8JVu$>
>>>
>>>
>>>
>>> It has never had a P-numbered proposal, and the area hasn't seen any
>>> movement that I'm aware of since circa 2018.
>>>
>>>
>>>
>>> https://github.com/WG21-SG14/SG14/issues/125
>>> <https://urldefense.com/v3/__https:/github.com/WG21-SG14/SG14/issues/125__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDXFqTwly$>
>>> inspired the implicit-move changes in C++20 (P1155 More Implicit Move).
>>>
>>> https://github.com/WG21-SG14/SG14/issues/150
>>> <https://urldefense.com/v3/__https:/github.com/WG21-SG14/SG14/issues/150__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDUy1jqED$>
>>> is still an important practical issue, where I happen to believe that the
>>> STL has chosen the wrong default as usual, and why I stopped caring much
>>> about the introduction of new type-erased types into the STL and started
>>> evangelizing type erasure *as a technique* so that people can just
>>> write their own.
>>>
>>>
>>> https://quuxplusone.github.io/blog/2019/03/27/design-space-for-std-function/
>>> <https://urldefense.com/v3/__https:/quuxplusone.github.io/blog/2019/03/27/design-space-for-std-function/__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDVs2z3X3$>
>>> is related.
>>>
>>>
>>>
>>> HTH,
>>>
>>> Arthur
>>>
>>> _______________________________________________
>>> Lib mailing list
>>> Lib_at_[hidden]
>>> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/lib
>>> <https://urldefense.com/v3/__https:/lists.isocpp.org/mailman/listinfo.cgi/lib__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDWOp6UJJ$>
>>> Link to this post: http://lists.isocpp.org/lib/2022/09/23737.php
>>> <https://urldefense.com/v3/__http:/lists.isocpp.org/lib/2022/09/23737.php__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDa3aziyr$>
>>>
>>> _______________________________________________
>>> SG14 mailing list
>>> SG14_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/sg14
>>> <https://urldefense.com/v3/__https:/lists.isocpp.org/mailman/listinfo.cgi/sg14__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDcXjZ4Fg$>
>>>
>>>
>>> INTERNAL - NI CONFIDENTIAL
>>>
>> _______________________________________________
>> Lib mailing list
>> Lib_at_[hidden]
>> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/lib
>> Link to this post: http://lists.isocpp.org/lib/2022/10/23961.php
>>
> _______________________________________________
> Lib mailing list
> Lib_at_[hidden]
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/lib
> Link to this post: http://lists.isocpp.org/lib/2022/10/23962.php
>
wrote:
>
>
> On Mon, 3 Oct 2022, 18:21 Patrice Roy via Lib, <lib_at_[hidden]>
> wrote:
>
>> Yeah, floated the idea of exposing the size at which SBO threshold is
>> set (through traits or something similar) thinking this would do the job
>> (people could use std::function on their own function objects and
>> static_assert on that object's size begin sufficiently small), but this did
>> not get much traction yet; there seems to be more appetite (if I read
>> SG14's wishes well) for a never-allocating cousin of std::function, at
>> least so far... Discussions on this topic are not closed yet, so we'll see.
>>
>
>
> What about making the constructor conditionally noexcept? The
> implementation knows whether a given type will be stored on the heap, and
> if that type can be constructed without throwing, so can easily expose that.
>
> What people care about is a property of the constructor, so why not make
> it part of the constructor signature?
>
> You can static assert is_nothrow_constructible.
>
One problem is that you would need to wrap it in something to make it
usable. Because lambdas are unutterable unique types you can't cleanly
separate the construction of the function from the static assertion,
especially if you want to stay in expression space (I hate reading code
that declares used-once lambda variables rather than defining them in the
argument position).
If you had that, you could easily declare a subclass of std::function which
only declared a forwarding constructor with the nothrow constraint. I think
that would make it a lot more ergonomic. But then that raises the question
of if you need to do that for it to be usable (in some domains) why not
just standardize std::noalloc_function (and noalloc_unique_function I
guess) so it can be used as a vocab type?
That said, we've made our implementation of UniqueFunction always allocate
and just hold a unique_ptr<Impl> because a) the smaller object and cheaper
moves are nice if you have a fast allocator, and b) we found it was very
common for lambdas to capture std::functions/UniqueFunctions, which means
that no matter how big the SBO size it would need to allocate anyway. So we
wouldn't have a use for that type, although I understand that others have
different tradeoffs that would make it indispensable.
>
>> Le lun. 3 oct. 2022 à 12:40, Ben Craig <ben.craig_at_[hidden]> a écrit :
>>
>>> Are there any examples of implementations that cause allocations,
>>> syscalls, or non-deterministic behavior for std::function when it is used
>>> with a function pointer, stateless lambda, or std::reference_wrapper? Is
>>> that std::function implementation claiming to be standards conforming?
>>>
>>> Best I can tell, std::function is already specified to meet these
>>> requirements as best as can be done with the current specification
>>> techniques.
>>>
>>> My suspicion is that the reluctance to use std::function is based off of
>>> some combination of general STL fear, and possibly some other requirements
>>> (e.g. user controllable small buffer optimization (SBO) instead of
>>> implementation tuned SBO).
>>>
>>>
>>>
>>> *From:* Lib <lib-bounces_at_[hidden]> *On Behalf Of *Björn
>>> Andersson via Lib
>>> *Sent:* Monday, October 3, 2022 11:58 AM
>>> *To:* sg14_at_[hidden]
>>> *Cc:* Björn Andersson <bjorn.andersson_at_[hidden]>; lib_at_[hidden];
>>> Patrice Roy <patricer_at_[hidden]>
>>> *Subject:* [EXTERNAL] Re: [isocpp-lib] [SG14] std::function
>>>
>>>
>>>
>>> Den ons 21 sep. 2022 kl 03:07 skrev Patrice Roy via SG14 <
>>> sg14_at_[hidden]>:
>>>
>>> Indeed, this type is part of a set of requests SG14 is working on these
>>> days.
>>>
>>>
>>>
>>> The problem (for low-latency people) is that there's no programmatic way
>>> to know, in user code, if a given std::function instantiation will or will
>>> not allocate, so that makes this type unusable for some use cases (in
>>> particular, many game development companies will not touch std:function
>>> precisely for this reason; they don't just need an optimization, they need
>>> a guarantee).
>>>
>>>
>>>
>>>
>>>
>>> Incidentally, this is exactly what the safety-critical people need as
>>> well: Not just the performance, but the guarantee of no
>>> syscall/deterministic behaviour.
>>>
>>>
>>>
>>> Thanks,
>>>
>>> Björn
>>>
>>>
>>>
>>>
>>>
>>> Cheers!
>>>
>>>
>>>
>>> Le mar. 20 sept. 2022 à 12:19, Arthur O'Dwyer via Lib <
>>> lib_at_[hidden]> a écrit :
>>>
>>> On Tue, Sep 20, 2022 at 9:22 AM Bjarne Stroustrup via Lib <
>>> lib_at_[hidden]> wrote:
>>>
>>> I thought we had a variant of std::function that didn't allocate on free
>>> store for simple functions; it didn't make it for C++20? Is it still in
>>> process? and if so where would I look for the current state of the
>>> proposal.
>>>
>>>
>>>
>>> [cc: SG14]
>>>
>>> SG14 has implemented, and I maintain, a type-erased
>>> `stdext::inplace_function<void(), Capacity, Align>` based on an informal
>>> proposal by Carl Cook in 2016:
>>>
>>> https://github.com/WG21-SG14/SG14/blob/master/SG14/inplace_function.h
>>> <https://urldefense.com/v3/__https:/github.com/WG21-SG14/SG14/blob/master/SG14/inplace_function.h__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDabzpusS$>
>>>
>>>
>>> https://github.com/Quuxplusone/SG14/blob/ajo/include/sg14/inplace_function.h
>>> <https://urldefense.com/v3/__https:/github.com/Quuxplusone/SG14/blob/ajo/include/sg14/inplace_function.h__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDVgSckTs$>
>>>
>>>
>>> https://groups.google.com/a/isocpp.org/g/std-proposals/c/vven2Om7Ha8/m/C7qQ_XwVCwAJ
>>> <https://urldefense.com/v3/__https:/groups.google.com/a/isocpp.org/g/std-proposals/c/vven2Om7Ha8/m/C7qQ_XwVCwAJ__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDQVrHXUy$>
>>>
>>>
>>> https://github.com/WG21-SG14/SG14/blob/master/Docs/Proposals/NonAllocatingStandardFunction.pdf
>>> <https://urldefense.com/v3/__https:/github.com/WG21-SG14/SG14/blob/master/Docs/Proposals/NonAllocatingStandardFunction.pdf__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDZ7r8JVu$>
>>>
>>>
>>>
>>> It has never had a P-numbered proposal, and the area hasn't seen any
>>> movement that I'm aware of since circa 2018.
>>>
>>>
>>>
>>> https://github.com/WG21-SG14/SG14/issues/125
>>> <https://urldefense.com/v3/__https:/github.com/WG21-SG14/SG14/issues/125__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDXFqTwly$>
>>> inspired the implicit-move changes in C++20 (P1155 More Implicit Move).
>>>
>>> https://github.com/WG21-SG14/SG14/issues/150
>>> <https://urldefense.com/v3/__https:/github.com/WG21-SG14/SG14/issues/150__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDUy1jqED$>
>>> is still an important practical issue, where I happen to believe that the
>>> STL has chosen the wrong default as usual, and why I stopped caring much
>>> about the introduction of new type-erased types into the STL and started
>>> evangelizing type erasure *as a technique* so that people can just
>>> write their own.
>>>
>>>
>>> https://quuxplusone.github.io/blog/2019/03/27/design-space-for-std-function/
>>> <https://urldefense.com/v3/__https:/quuxplusone.github.io/blog/2019/03/27/design-space-for-std-function/__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDVs2z3X3$>
>>> is related.
>>>
>>>
>>>
>>> HTH,
>>>
>>> Arthur
>>>
>>> _______________________________________________
>>> Lib mailing list
>>> Lib_at_[hidden]
>>> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/lib
>>> <https://urldefense.com/v3/__https:/lists.isocpp.org/mailman/listinfo.cgi/lib__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDWOp6UJJ$>
>>> Link to this post: http://lists.isocpp.org/lib/2022/09/23737.php
>>> <https://urldefense.com/v3/__http:/lists.isocpp.org/lib/2022/09/23737.php__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDa3aziyr$>
>>>
>>> _______________________________________________
>>> SG14 mailing list
>>> SG14_at_[hidden]
>>> https://lists.isocpp.org/mailman/listinfo.cgi/sg14
>>> <https://urldefense.com/v3/__https:/lists.isocpp.org/mailman/listinfo.cgi/sg14__;!!FbZ0ZwI3Qg!sCasIrYyAVDki7IUP5cdc4SyHRAN353p0v57WEjq1yngDBDosdG3aIVmMqax8UEo369IDcXjZ4Fg$>
>>>
>>>
>>> INTERNAL - NI CONFIDENTIAL
>>>
>> _______________________________________________
>> Lib mailing list
>> Lib_at_[hidden]
>> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/lib
>> Link to this post: http://lists.isocpp.org/lib/2022/10/23961.php
>>
> _______________________________________________
> Lib mailing list
> Lib_at_[hidden]
> Subscription: https://lists.isocpp.org/mailman/listinfo.cgi/lib
> Link to this post: http://lists.isocpp.org/lib/2022/10/23962.php
>
Received on 2022-10-04 08:47:48