MSVC exhibits unexpected behavior while copying lambda using memcpy()

54 Views Asked by At

The reason I am asking this is because I need to store std::function in an in-house vector we have in company that internally does memcpy i.e. no copy/move operator.

This means all the element we can put in our container need to be trivially-copyable.

I have created a small program to replicate the issue. The following program seems to generate expected results when compiled with gcc but with MSVC it does not seem to work correctly-

#include<iostream>
#include<functional>
#include<cstring>
using namespace std;

using VAR = void();
struct Abc
{
    std::function<VAR> fn;
};

struct Test{
    int i;
};

void openTest(const Test& a) noexcept
{
    cout<<"In Test"<<a.i<<endl;
};

void foo(Abc& abc, const Test& test)
{
    abc.fn = [test]() noexcept{ openTest(test);};
}
int main()
{
    Abc arr[2];

    for(int i=0;i<2;++i)
    {
        Abc abc;
        memset(&abc,0, sizeof(Abc));

        Test test{i*8+1};
        foo(abc,test);
        memcpy(&arr[i],&abc,sizeof(Abc));
        //To show the result **while** the array is populated
        arr[i].fn();
    }
    //To show the result **after** the array is populated
    for(int i=0;i<2;++i)
        arr[i].fn();
}

Code Executed here : https://godbolt.org/z/3fns5Kej3
The execution results using x86-64 gcc 12.2 -

In Test1
In Test9
In Test1
In Test9

The execution results using x86 msvc v19.latest -

In Test1
In Test9
In Test9
In Test9

Debugging the program, I see that during the second for loop iteration (i==1), the memcpy updates both the arr[0].fn and arr[1].fn.

Can someone explain why I am observing the incorrect behavior with MSCV?

0

There are 0 best solutions below