• MSVC-bug

    From Bonita Montero@3:633/280.2 to All on Tue Feb 13 22:07:14 2024
    If you initialize a function<>-object with a reference_wrapper it
    is guaranteed that the function<>-object references an external function-object without any memory allocation. libstdc++ and libc++
    don't allocate any memory with such function<>-objects according
    to the standard, but MSVC does allocate external memory.

    #include <iostream>
    #include <functional>

    using namespace std;

    void *operator new( size_t n )
    {
    cout << "alloc" << endl;
    void *p = malloc( n );
    if( !p )
    throw bad_alloc();
    return p;
    }

    void operator delete( void *p )
    {
    free( p );
    }

    int main()
    {
    function<void ()> fn;
    string str( "hello word" );
    auto lam = [str = str]() { cout << str << endl; };
    fn = ref( lam );
    fn();
    }

    --- MBSE BBS v1.0.8.4 (Linux-x86_64)
    * Origin: A noiseless patient Spider (3:633/280.2@fidonet)
  • From Paavo Helde@3:633/280.2 to All on Fri Feb 16 00:34:35 2024
    13.02.2024 13:07 Bonita Montero kirjutas:
    If you initialize a function<>-object with a reference_wrapper it
    isÿ guaranteed that the function<>-object references an external function-object without any memory allocation. libstdc++ and libc++
    don't allocate any memory with such function<>-objects according
    to the standard, but MSVC does allocate external memory.

    Cannot confirm that. MSVC++ 2022 x64 Release mode does not print "alloc"
    at all for this program. In Debug mode there are a couple of allocs, but
    these seem to be related to some std::string internals, not the
    reference wrapper.


    #include <iostream>
    #include <functional>

    using namespace std;

    void *operator new( size_t n )
    {
    ÿÿÿÿcout << "alloc" << endl;
    ÿÿÿÿvoid *p = malloc( n );
    ÿÿÿÿif( !p )
    ÿÿÿÿÿÿÿ throw bad_alloc();
    ÿÿÿÿreturn p;
    }

    void operator delete( void *p )
    {
    ÿÿÿÿfree( p );
    }

    int main()
    {
    ÿÿÿÿfunction<void ()> fn;
    ÿÿÿÿstring str( "hello word" );
    ÿÿÿÿauto lam = [str = str]() { cout << str << endl; };
    ÿÿÿÿfn = ref( lam );
    ÿÿÿÿfn();
    }


    --- MBSE BBS v1.0.8.4 (Linux-x86_64)
    * Origin: A noiseless patient Spider (3:633/280.2@fidonet)
  • From Bonita Montero@3:633/280.2 to All on Thu Feb 15 22:20:02 2024
    Am 15.02.2024 um 14:34 schrieb Paavo Helde:

    Cannot confirm that. MSVC++ 2022 x64 Release mode does not print "alloc"
    at all for this program. In Debug mode there are a couple of allocs, but these seem to be related to some std::string internals, not the
    reference wrapper.

    Sorry, I relied on the Debug build.
    With Release build there are no allocations.
    But I think the Debug build should also be up to the standard.


    --- MBSE BBS v1.0.8.4 (Linux-x86_64)
    * Origin: A noiseless patient Spider (3:633/280.2@fidonet)
  • From Paavo Helde@3:633/280.2 to All on Fri Feb 16 09:11:12 2024
    15.02.2024 13:20 Bonita Montero kirjutas:
    Am 15.02.2024 um 14:34 schrieb Paavo Helde:

    Cannot confirm that. MSVC++ 2022 x64 Release mode does not print
    "alloc" at all for this program. In Debug mode there are a couple of
    allocs, but these seem to be related to some std::string internals,
    not the reference wrapper.

    Sorry, I relied on the Debug build.
    With Release build there are no allocations.
    But I think the Debug build should also be up to the standard.


    Constructing and copying std::strings is allowed to allocate dynamic
    memory. Make your string a bit longer and you will see allocations also
    in Release builds.


    --- MBSE BBS v1.0.8.4 (Linux-x86_64)
    * Origin: A noiseless patient Spider (3:633/280.2@fidonet)
  • From Bonita Montero@3:633/280.2 to All on Fri Feb 16 19:17:11 2024
    Am 15.02.2024 um 23:11 schrieb Paavo Helde:

    Constructing and copying std::strings is allowed to allocate dynamic
    memory. Make your string a bit longer and you will see allocations
    also in Release builds.

    The small string optimization is nothing which is guaranteed.
    Initializing a function object with a reference_wrapper is
    guaranteed to be without memory allocation.


    --- MBSE BBS v1.0.8.4 (Linux-x86_64)
    * Origin: A noiseless patient Spider (3:633/280.2@fidonet)
  • From Andrey Tarasevich@3:633/280.2 to All on Fri Mar 1 15:45:12 2024
    On 02/16/24 12:17 AM, Bonita Montero wrote:

    The small string optimization is nothing which is guaranteed.
    Initializing a function object with a reference_wrapper is
    guaranteed to be without memory allocation.


    Why do you keep spewing this nonsense?

    You have been told very clearly already that in this case
    `std::function<>` does not perform any memory allocation in Visual
    Studio. Neither in Debug nor in Release builds. You imagined it.

    --
    Best regards,
    Andrey

    --- MBSE BBS v1.0.8.4 (Linux-x86_64)
    * Origin: A noiseless patient Spider (3:633/280.2@fidonet)
  • From Bonita Montero@3:633/280.2 to All on Sat Mar 2 00:53:58 2024
    Am 01.03.2024 um 05:45 schrieb Andrey Tarasevich:
    On 02/16/24 12:17 AM, Bonita Montero wrote:

    The small string optimization is nothing which is guaranteed.
    Initializing a function object with a reference_wrapper is
    guaranteed to be without memory allocation.


    Why do you keep spewing this nonsense?

    You have been told very clearly already that in this case
    `std::function<>` does not perform any memory allocation in Visual
    Studio. Neither in Debug nor in Release builds. You imagined it.

    Not true ! This code prints "alloc" first with MSVC
    and a Debug-build, but not with Release-builds.

    #include <iostream>
    #include <functional>

    using namespace std;

    void *operator new( size_t n )
    {
    cout << "alloc" << endl;
    void *p = malloc( n );
    if( !p )
    throw bad_alloc();
    return p;
    }

    void operator delete( void *p )
    {
    free( p );
    }

    int main()
    {
    function<void ()> fn;
    string str( "hello word" );
    auto lam = [&str]() { cout << str << endl; };
    fn = ref( lam );
    fn();
    }

    --- MBSE BBS v1.0.8.4 (Linux-x86_64)
    * Origin: A noiseless patient Spider (3:633/280.2@fidonet)
  • From Andrey Tarasevich@3:633/280.2 to All on Sat Mar 2 13:44:12 2024
    On 03/01/24 5:53 AM, Bonita Montero wrote:

    You have been told very clearly already that in this case
    `std::function<>` does not perform any memory allocation in Visual
    Studio. Neither in Debug nor in Release builds. You imagined it.

    Not true ! This code prints "alloc" first with MSVC
    and a Debug-build, but not with Release-builds.

    ???

    As you have already been told, your "alloc" originates from
    `std::string`, and has nothing to do with `std::function<>`.

    Do this

    ...
    int main()
    {
    function<void ()> fn;
    string str( "hello word" );
    auto lam = [&str]() { cout << str << endl; };

    cout << "---" << endl;

    fn = ref( lam );

    cout << "---" << endl;

    fn();
    }

    Your "alloc" is printed before the first "---".

    --
    Best regards,
    Andrey


    --- MBSE BBS v1.0.8.4 (Linux-x86_64)
    * Origin: A noiseless patient Spider (3:633/280.2@fidonet)
  • From Bonita Montero@3:633/280.2 to All on Sat Mar 2 17:36:00 2024
    Am 02.03.2024 um 03:44 schrieb Andrey Tarasevich:
    On 03/01/24 5:53 AM, Bonita Montero wrote:

    You have been told very clearly already that in this case
    `std::function<>` does not perform any memory allocation in Visual
    Studio. Neither in Debug nor in Release builds. You imagined it.

    Not true ! This code prints "alloc" first with MSVC
    and a Debug-build, but not with Release-builds.

    ???

    As you have already been told, your "alloc" originates from
    `std::string`, ...

    No, from the function allocation. Just single-step the code yourself.


    Do this

    ÿ ...
    ÿ int main()
    ÿ {
    ÿÿÿ function<void ()> fn;
    ÿÿÿ string str( "hello word" );
    ÿÿÿ auto lam = [&str]() { cout << str << endl; };

    ÿÿÿ cout << "---" << endl;

    ÿÿÿ fn = ref( lam );

    ÿÿÿ cout << "---" << endl;

    ÿÿÿ fn();
    ÿ }

    Your "alloc" is printed before the first "---".



    --- MBSE BBS v1.0.8.4 (Linux-x86_64)
    * Origin: A noiseless patient Spider (3:633/280.2@fidonet)
  • From Andrey Tarasevich@3:633/280.2 to All on Sun Mar 3 07:38:12 2024
    On 03/01/24 10:36 PM, Bonita Montero wrote:
    Am 02.03.2024 um 03:44 schrieb Andrey Tarasevich:
    On 03/01/24 5:53 AM, Bonita Montero wrote:

    You have been told very clearly already that in this case
    `std::function<>` does not perform any memory allocation in Visual
    Studio. Neither in Debug nor in Release builds. You imagined it.

    Not true ! This code prints "alloc" first with MSVC
    and a Debug-build, but not with Release-builds.

    ???

    As you have already been told, your "alloc" originates from
    `std::string`, ...

    No, from the function allocation. Just single-step the code yourself.

    .... which is exactly what I did in the first place.

    Once again: the Debug config of the _original_ version of the code emits
    two allocations, both of which originate in `std::string`. The first one
    is allocation of some sort of "container proxy" in `std::string`s
    constructor. Another is the same thing in your `[str = str]`.

    The updated version of the code (with '[&str]`) emits only one
    allocation: the same "container proxy" in `std::string`s constuctor.

    No allocations are made for `std::function<>` in either version.

    --
    Best regards,
    Andrey


    --- MBSE BBS v1.0.8.4 (Linux-x86_64)
    * Origin: A noiseless patient Spider (3:633/280.2@fidonet)