Discussion:
MSVC-bug
(too old to reply)
Bonita Montero
2024-02-13 11:07:14 UTC
Permalink
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();
}
Paavo Helde
2024-02-15 13:34:35 UTC
Permalink
Post by Bonita Montero
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.
Post by Bonita Montero
#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();
}
Bonita Montero
2024-02-15 11:20:02 UTC
Permalink
Post by 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.
Bonita Montero
2024-02-16 08:17:11 UTC
Permalink
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.
Andrey Tarasevich
2024-03-01 04:45:12 UTC
Permalink
Post by Bonita Montero
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
Bonita Montero
2024-03-01 13:53:58 UTC
Permalink
Post by Andrey Tarasevich
Post by Bonita Montero
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();
}
Andrey Tarasevich
2024-03-02 02:44:12 UTC
Permalink
Post by Bonita Montero
Post by Andrey Tarasevich
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
Bonita Montero
2024-03-02 06:36:00 UTC
Permalink
Post by Andrey Tarasevich
Post by Bonita Montero
Post by Andrey Tarasevich
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.
Post by Andrey Tarasevich
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 "---".
Andrey Tarasevich
2024-03-02 20:38:12 UTC
Permalink
Post by Bonita Montero
Post by Andrey Tarasevich
Post by Bonita Montero
Post by Andrey Tarasevich
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
Loading...